diff --git a/apps/api/src/api/v1/agents.py b/apps/api/src/api/v1/agents.py index 573f7cf2f..ff1875769 100644 --- a/apps/api/src/api/v1/agents.py +++ b/apps/api/src/api/v1/agents.py @@ -115,6 +115,9 @@ from src.services.ai_agent_report_runtime_fixture_readback import ( from src.services.ai_agent_report_runtime_readiness import ( load_latest_ai_agent_report_runtime_readiness, ) +from src.services.ai_agent_report_status_board import ( + load_latest_ai_agent_report_status_board, +) from src.services.ai_agent_report_truth_actionability_review import ( load_latest_ai_agent_report_truth_actionability_review, ) @@ -947,6 +950,35 @@ async def get_agent_report_automation_review() -> dict[str, Any]: ) from exc +@router.get( + "/agent-report-status-board", + response_model=dict[str, Any], + summary="取得 AI Agent 日週月報與工作狀態總覽", + description=( + "讀取最新已提交的 P2-108 AI Agent 日報、週報、月報完成狀態、" + "OpenClaw / Hermes / NemoTron 工作量、圖表化狀態、Telegram 草案與自動優化邊界;" + "此端點不排程實發、不送 Telegram、不寫 Gateway queue、不寫讀報回執、" + "不啟動 AI 分析 worker、不執行生產優化、不讀 secret、不回傳內部協作內容。" + ), +) +async def get_agent_report_status_board() -> dict[str, Any]: + """Return the latest read-only AI Agent report status board.""" + try: + payload = await asyncio.to_thread(load_latest_ai_agent_report_status_board) + return redact_public_lan_topology(payload) + except FileNotFoundError as exc: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=str(exc), + ) from exc + except (json.JSONDecodeError, ValueError) as exc: + logger.error("ai_agent_report_status_board_invalid", error=str(exc)) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="AI Agent 日週月報與工作狀態總覽無效", + ) from exc + + @router.get( "/agent-report-runtime-readiness", response_model=dict[str, Any], diff --git a/apps/api/src/services/ai_agent_report_status_board.py b/apps/api/src/services/ai_agent_report_status_board.py new file mode 100644 index 000000000..344d55cc7 --- /dev/null +++ b/apps/api/src/services/ai_agent_report_status_board.py @@ -0,0 +1,273 @@ +""" +AI Agent report status board snapshot. + +Loads the latest committed P2-108 daily / weekly / monthly report status board. +This module exposes a read-only management summary only. It never schedules +reports, sends Telegram, writes Gateway queues, records read receipts, starts +AI analysis workers, or writes production optimization results. +""" + +from __future__ import annotations + +import json +from pathlib import Path +from typing import Any + +from src.services.snapshot_paths import default_evaluations_dir + +_DEFAULT_EVALUATIONS_DIR = default_evaluations_dir(Path(__file__)) +_SNAPSHOT_PATTERN = "ai_agent_report_status_board_*.json" +_SCHEMA_VERSION = "ai_agent_report_status_board_v1" +_RUNTIME_AUTHORITY = "report_status_board_only_no_live_send_or_write" +_FORBIDDEN_DISPLAY_TERMS = ( + "工作視窗", + "對話內容", + "批准!繼續", + "In app browser", + "My request for Codex", + "browser_context", + "codex_user_message", + "prompt_text", + "raw prompt", + "raw_prompt", + "private reasoning", + "private_reasoning", + "chain of thought", + "chain_of_thought", + "authorization_header", + "authorization header", + "secret value", + "secret_value", + "raw payload", + "raw_payload", + "raw Telegram payload", + "raw_telegram_payload", +) + + +def load_latest_ai_agent_report_status_board( + evaluations_dir: Path | None = None, +) -> dict[str, Any]: + """Load the newest committed AI Agent report status board snapshot.""" + directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR + candidates = sorted(directory.glob(_SNAPSHOT_PATTERN)) + if not candidates: + raise FileNotFoundError(f"no AI Agent report status board snapshots found in {directory}") + + latest = candidates[-1] + with latest.open(encoding="utf-8") as handle: + payload = json.load(handle) + + if not isinstance(payload, dict): + raise ValueError(f"{latest}: expected JSON object") + _require_schema(payload, str(latest)) + _require_completion_truth(payload, str(latest)) + _require_report_cards(payload, str(latest)) + _require_agent_status_reports(payload, str(latest)) + _require_visible_charts(payload, str(latest)) + _require_operator_answers(payload, str(latest)) + _require_activation_boundaries(payload, str(latest)) + _require_display_redaction(payload, str(latest)) + _require_no_forbidden_display_terms(payload, str(latest)) + _require_rollup_consistency(payload, str(latest)) + return payload + + +def _require_schema(payload: dict[str, Any], label: str) -> None: + if payload.get("schema_version") != _SCHEMA_VERSION: + raise ValueError(f"{label}: expected schema_version={_SCHEMA_VERSION}") + status = payload.get("program_status") or {} + if status.get("read_only_mode") is not True: + raise ValueError(f"{label}: program_status.read_only_mode must be true") + if status.get("runtime_authority") != _RUNTIME_AUTHORITY: + raise ValueError(f"{label}: runtime_authority must remain {_RUNTIME_AUTHORITY}") + if status.get("current_task_id") != "P2-108": + raise ValueError(f"{label}: current_task_id must be P2-108") + if status.get("overall_completion_percent") != 100: + raise ValueError(f"{label}: P2-108 status board must be 100 percent complete") + + +def _require_completion_truth(payload: dict[str, Any], label: str) -> None: + truth = payload.get("report_completion_truth") or {} + required_true = { + "daily_report_visible", + "weekly_report_visible", + "monthly_report_visible", + "per_agent_status_visible", + "workload_metrics_visible", + "chart_package_visible", + "telegram_digest_draft_visible", + "high_risk_human_approval_required", + } + missing = sorted(field for field in required_true if truth.get(field) is not True) + if missing: + raise ValueError(f"{label}: report visibility truth flags must remain true: {missing}") + + required_false = { + "live_report_delivery_enabled", + "ai_post_report_analysis_enabled", + "medium_low_auto_optimization_enabled", + } + unsafe = sorted(field for field in required_false if truth.get(field) is not False) + if unsafe: + raise ValueError(f"{label}: live report automation flags must remain false: {unsafe}") + + zero_counts = { + "live_telegram_send_count_24h", + "live_auto_optimization_count_24h", + } + non_zero = sorted(field for field in zero_counts if truth.get(field) != 0) + if non_zero: + raise ValueError(f"{label}: live report counters must remain zero: {non_zero}") + + +def _require_report_cards(payload: dict[str, Any], label: str) -> None: + cards = payload.get("report_status_cards") or [] + cadence_ids = {card.get("cadence_id") for card in cards} + if cadence_ids != {"daily", "weekly", "monthly"}: + raise ValueError(f"{label}: report cards must include daily, weekly, monthly") + for card in cards: + cadence_id = card.get("cadence_id") + if card.get("completion_percent") != 100: + raise ValueError(f"{label}: report {cadence_id} must be 100 percent visible") + if card.get("contract_state") != "visible_contract_ready": + raise ValueError(f"{label}: report {cadence_id} contract_state must be visible_contract_ready") + if card.get("delivery_state") != "draft_only": + raise ValueError(f"{label}: report {cadence_id} delivery_state must remain draft_only") + if card.get("live_delivery_count") != 0: + raise ValueError(f"{label}: report {cadence_id} live_delivery_count must remain zero") + if not card.get("next_gate"): + raise ValueError(f"{label}: report {cadence_id} must include next_gate") + + +def _require_agent_status_reports(payload: dict[str, Any], label: str) -> None: + reports = payload.get("agent_status_reports") or [] + agent_ids = {report.get("agent_id") for report in reports} + if agent_ids != {"openclaw", "hermes", "nemotron"}: + raise ValueError(f"{label}: agent status reports must include OpenClaw, Hermes, NemoTron") + for report in reports: + agent_id = report.get("agent_id") + total = report.get("work_units_total") + done = report.get("work_units_done") + waiting = report.get("work_units_waiting_approval") + if not isinstance(total, int) or not isinstance(done, int) or not isinstance(waiting, int): + raise ValueError(f"{label}: agent {agent_id} work units must be integers") + if done + waiting != total: + raise ValueError(f"{label}: agent {agent_id} done + waiting must equal total") + if report.get("live_runtime_work_units_24h") != 0: + raise ValueError(f"{label}: agent {agent_id} live_runtime_work_units_24h must remain zero") + if not report.get("primary_role") or not report.get("status_note"): + raise ValueError(f"{label}: agent {agent_id} must include role and status note") + + +def _require_visible_charts(payload: dict[str, Any], label: str) -> None: + charts = payload.get("visible_charts") or [] + chart_ids = {chart.get("chart_id") for chart in charts} + required = {"report_cadence_completion", "agent_workload_status", "runtime_activation_boundary"} + if chart_ids != required: + raise ValueError(f"{label}: visible charts must match {sorted(required)}") + for chart in charts: + if not chart.get("series"): + raise ValueError(f"{label}: chart {chart.get('chart_id')} must include series") + + +def _require_operator_answers(payload: dict[str, Any], label: str) -> None: + answers = payload.get("operator_answer_cards") or [] + answer_ids = {answer.get("answer_id") for answer in answers} + required = { + "daily_weekly_monthly_complete", + "per_agent_status_visible", + "telegram_and_auto_optimization_boundary", + "high_risk_review_policy", + } + if answer_ids != required: + raise ValueError(f"{label}: operator answers must match {sorted(required)}") + complete_answers = [answer for answer in answers if answer.get("status") == "complete"] + if len(complete_answers) < 2: + raise ValueError(f"{label}: at least report and per-agent answers must be complete") + + +def _require_activation_boundaries(payload: dict[str, Any], label: str) -> None: + boundaries = payload.get("activation_boundaries") or {} + required_false = { + "scheduler_enabled", + "gateway_queue_write_enabled", + "telegram_send_enabled", + "report_receipt_write_enabled", + "ai_analysis_run_enabled", + "medium_low_auto_execution_enabled", + "production_optimization_write_enabled", + } + unsafe = sorted(field for field in required_false if boundaries.get(field) is not False) + if unsafe: + raise ValueError(f"{label}: activation boundaries must remain false: {unsafe}") + if boundaries.get("high_risk_requires_human_approval") is not True: + raise ValueError(f"{label}: high_risk_requires_human_approval must remain true") + + +def _require_display_redaction(payload: dict[str, Any], label: str) -> None: + contract = payload.get("display_redaction_contract") or {} + if contract.get("redaction_required") is not True: + raise ValueError(f"{label}: display redaction is required") + forbidden_true = { + "raw_prompt_display_allowed", + "private_reasoning_display_allowed", + "secret_value_display_allowed", + "internal_transcript_display_allowed", + } + unsafe = sorted(field for field in forbidden_true if contract.get(field) is not False) + if unsafe: + raise ValueError(f"{label}: display redaction fields must remain false: {unsafe}") + + +def _require_no_forbidden_display_terms(payload: Any, label: str) -> None: + strings = _collect_strings(payload) + found = sorted({term for term in _FORBIDDEN_DISPLAY_TERMS for value in strings if term in value}) + if found: + raise ValueError(f"{label}: forbidden display terms found: {found}") + + +def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None: + rollups = payload.get("rollups") or {} + report_cards = payload.get("report_status_cards") or [] + agents = payload.get("agent_status_reports") or [] + charts = payload.get("visible_charts") or [] + answers = payload.get("operator_answer_cards") or [] + expected = { + "report_card_count": len(report_cards), + "agent_status_count": len(agents), + "visible_chart_count": len(charts), + "operator_answer_count": len(answers), + "completed_report_count": len([card for card in report_cards if card.get("completion_percent") == 100]), + "workload_unit_total": sum(agent.get("work_units_total", 0) for agent in agents), + "workload_done_total": sum(agent.get("work_units_done", 0) for agent in agents), + "workload_waiting_approval_total": sum(agent.get("work_units_waiting_approval", 0) for agent in agents), + "live_delivery_count": sum(card.get("live_delivery_count", 0) for card in report_cards), + "live_telegram_send_count": 0, + "live_runtime_work_units": sum(agent.get("live_runtime_work_units_24h", 0) for agent in agents), + "live_auto_optimization_count": 0, + "high_risk_requires_human_approval": True, + } + mismatched = { + key: {"expected": value, "actual": rollups.get(key)} + for key, value in expected.items() + if rollups.get(key) != value + } + if mismatched: + raise ValueError(f"{label}: rollup counts must match payload sections: {mismatched}") + + +def _collect_strings(value: Any) -> list[str]: + if isinstance(value, str): + return [value] + if isinstance(value, list): + strings: list[str] = [] + for item in value: + strings.extend(_collect_strings(item)) + return strings + if isinstance(value, dict): + strings: list[str] = [] + for item in value.values(): + strings.extend(_collect_strings(item)) + return strings + return [] diff --git a/apps/api/tests/test_ai_agent_report_status_board.py b/apps/api/tests/test_ai_agent_report_status_board.py new file mode 100644 index 000000000..ce6e6815d --- /dev/null +++ b/apps/api/tests/test_ai_agent_report_status_board.py @@ -0,0 +1,117 @@ +import copy +import json + +import pytest + +from src.services.ai_agent_report_status_board import load_latest_ai_agent_report_status_board + + +def _write_snapshot(tmp_path, payload): + path = tmp_path / "ai_agent_report_status_board_2026-06-13.json" + path.write_text(json.dumps(payload), encoding="utf-8") + return path + + +def test_load_latest_ai_agent_report_status_board(): + data = load_latest_ai_agent_report_status_board() + + assert data["schema_version"] == "ai_agent_report_status_board_v1" + assert data["program_status"]["current_task_id"] == "P2-108" + assert data["program_status"]["next_task_id"] == "P2-109" + assert data["program_status"]["overall_completion_percent"] == 100 + assert data["report_completion_truth"]["daily_report_visible"] is True + assert data["report_completion_truth"]["weekly_report_visible"] is True + assert data["report_completion_truth"]["monthly_report_visible"] is True + assert data["report_completion_truth"]["per_agent_status_visible"] is True + assert data["report_completion_truth"]["live_report_delivery_enabled"] is False + assert data["report_completion_truth"]["live_telegram_send_count_24h"] == 0 + assert data["report_completion_truth"]["medium_low_auto_optimization_enabled"] is False + assert data["report_completion_truth"]["high_risk_human_approval_required"] is True + assert data["rollups"]["report_card_count"] == 3 + assert data["rollups"]["agent_status_count"] == 3 + assert data["rollups"]["visible_chart_count"] == 3 + assert data["rollups"]["operator_answer_count"] == 4 + assert data["rollups"]["completed_report_count"] == 3 + assert data["rollups"]["workload_unit_total"] == 91 + assert data["rollups"]["workload_done_total"] == 79 + assert data["rollups"]["workload_waiting_approval_total"] == 12 + assert data["rollups"]["live_delivery_count"] == 0 + assert data["rollups"]["live_runtime_work_units"] == 0 + assert data["rollups"]["live_auto_optimization_count"] == 0 + + +def test_rejects_missing_monthly_card(tmp_path): + data = load_latest_ai_agent_report_status_board() + bad = copy.deepcopy(data) + bad["report_status_cards"] = [ + card for card in bad["report_status_cards"] if card["cadence_id"] != "monthly" + ] + bad["rollups"]["report_card_count"] = len(bad["report_status_cards"]) + bad["rollups"]["completed_report_count"] = len(bad["report_status_cards"]) + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="daily, weekly, monthly"): + load_latest_ai_agent_report_status_board(tmp_path) + + +def test_rejects_missing_agent_status(tmp_path): + data = load_latest_ai_agent_report_status_board() + bad = copy.deepcopy(data) + bad["agent_status_reports"] = [ + agent for agent in bad["agent_status_reports"] if agent["agent_id"] != "nemotron" + ] + bad["rollups"]["agent_status_count"] = len(bad["agent_status_reports"]) + bad["rollups"]["workload_unit_total"] = sum( + agent["work_units_total"] for agent in bad["agent_status_reports"] + ) + bad["rollups"]["workload_done_total"] = sum( + agent["work_units_done"] for agent in bad["agent_status_reports"] + ) + bad["rollups"]["workload_waiting_approval_total"] = sum( + agent["work_units_waiting_approval"] for agent in bad["agent_status_reports"] + ) + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="OpenClaw, Hermes, NemoTron"): + load_latest_ai_agent_report_status_board(tmp_path) + + +def test_rejects_live_telegram_send(tmp_path): + data = load_latest_ai_agent_report_status_board() + bad = copy.deepcopy(data) + bad["report_completion_truth"]["live_telegram_send_count_24h"] = 1 + bad["rollups"]["live_telegram_send_count"] = 1 + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="live report counters"): + load_latest_ai_agent_report_status_board(tmp_path) + + +def test_rejects_scheduler_enabled(tmp_path): + data = load_latest_ai_agent_report_status_board() + bad = copy.deepcopy(data) + bad["activation_boundaries"]["scheduler_enabled"] = True + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="activation boundaries"): + load_latest_ai_agent_report_status_board(tmp_path) + + +def test_rejects_forbidden_display_terms(tmp_path): + data = load_latest_ai_agent_report_status_board() + bad = copy.deepcopy(data) + bad["operator_answer_cards"][0]["answer"] = "請把工作視窗逐字稿顯示出來" + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="forbidden display terms"): + load_latest_ai_agent_report_status_board(tmp_path) + + +def test_rejects_rollup_mismatch(tmp_path): + data = load_latest_ai_agent_report_status_board() + bad = copy.deepcopy(data) + bad["rollups"]["workload_unit_total"] = 999 + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="rollup counts"): + load_latest_ai_agent_report_status_board(tmp_path) diff --git a/apps/api/tests/test_ai_agent_report_status_board_api.py b/apps/api/tests/test_ai_agent_report_status_board_api.py new file mode 100644 index 000000000..37557259f --- /dev/null +++ b/apps/api/tests/test_ai_agent_report_status_board_api.py @@ -0,0 +1,78 @@ +from fastapi.testclient import TestClient + +from src.main import app + + +_PUBLIC_FORBIDDEN_TERMS = [ + "工作視窗", + "對話內容", + "批准!繼續", + "In app browser", + "My request for Codex", + "browser_context", + "codex_user_message", + "prompt_text", + "raw prompt", + "raw_prompt", + "raw payload", + "raw_payload", + "private reasoning", + "chain_of_thought", + "authorization header", + "authorization_header", + "secret value", + "secret_value", +] + + +def _collect_strings(value): + if isinstance(value, str): + return [value] + if isinstance(value, list): + strings = [] + for item in value: + strings.extend(_collect_strings(item)) + return strings + if isinstance(value, dict): + strings = [] + for item in value.values(): + strings.extend(_collect_strings(item)) + return strings + return [] + + +def test_get_ai_agent_report_status_board_api(): + client = TestClient(app) + response = client.get("/api/v1/agents/agent-report-status-board") + + assert response.status_code == 200 + data = response.json() + assert data["schema_version"] == "ai_agent_report_status_board_v1" + assert data["program_status"]["current_task_id"] == "P2-108" + assert data["program_status"]["next_task_id"] == "P2-109" + assert data["program_status"]["overall_completion_percent"] == 100 + assert data["report_completion_truth"]["daily_report_visible"] is True + assert data["report_completion_truth"]["weekly_report_visible"] is True + assert data["report_completion_truth"]["monthly_report_visible"] is True + assert data["report_completion_truth"]["per_agent_status_visible"] is True + assert data["report_completion_truth"]["live_report_delivery_enabled"] is False + assert data["report_completion_truth"]["live_telegram_send_count_24h"] == 0 + assert data["report_completion_truth"]["live_auto_optimization_count_24h"] == 0 + assert data["rollups"]["report_card_count"] == 3 + assert data["rollups"]["agent_status_count"] == 3 + assert data["rollups"]["visible_chart_count"] == 3 + assert data["rollups"]["operator_answer_count"] == 4 + assert data["rollups"]["workload_unit_total"] == 91 + assert data["rollups"]["live_delivery_count"] == 0 + assert data["rollups"]["live_runtime_work_units"] == 0 + assert data["rollups"]["live_auto_optimization_count"] == 0 + + +def test_get_ai_agent_report_status_board_api_redacts_public_terms(): + client = TestClient(app) + response = client.get("/api/v1/agents/agent-report-status-board") + + assert response.status_code == 200 + all_text = "\n".join(_collect_strings(response.json())) + for term in _PUBLIC_FORBIDDEN_TERMS: + assert term not in all_text diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index acb7dc02f..968cd460b 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -4180,6 +4180,49 @@ "critical": "關鍵阻擋" } }, + "reportStatusBoard": { + "title": "P2-108 日週月報與 Agent 工作狀態總覽", + "source": "{generated} · {current} → {next}", + "truthTitle": "報告完成狀態", + "boundaryTitle": "live 啟用邊界", + "metrics": { + "overall": "P2-108 進度", + "reports": "報告", + "agents": "Agent", + "charts": "圖表", + "workload": "工作量", + "done": "已完成", + "waitingApproval": "待審核", + "liveDelivery": "live 發送", + "liveOptimization": "live 優化" + }, + "flags": { + "daily": "日報可見: {value}", + "weekly": "週報可見: {value}", + "monthly": "月報可見: {value}", + "perAgent": "Agent 狀態可見: {value}", + "telegram": "Telegram 草案: {value}", + "scheduler": "scheduler: {value}", + "queue": "queue write: {value}", + "send": "Telegram send: {value}", + "analysis": "AI analysis: {value}", + "optimization": "production optimization: {value}", + "highApproval": "高風險人工審核: {value}" + }, + "labels": { + "completion": "完成度", + "reportDetail": "章節 {sections};圖表 {charts};工作量 {work};live {live}", + "workDone": "工作完成", + "agentDetail": "{done}/{total} 已完成;{approval} 待審核;24h live {live}", + "sections": "報告章節 {count}", + "recommendations": "分析建議 {count}" + }, + "answerStatuses": { + "complete": "已完成", + "guarded": "受閘門保護", + "next_gate": "下一關" + } + }, "reportRuntimeReadiness": { "title": "P2-403L 報表派送與自動處理啟動閘門", "source": "{generated} · {current} → {next}", diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index acb7dc02f..968cd460b 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -4180,6 +4180,49 @@ "critical": "關鍵阻擋" } }, + "reportStatusBoard": { + "title": "P2-108 日週月報與 Agent 工作狀態總覽", + "source": "{generated} · {current} → {next}", + "truthTitle": "報告完成狀態", + "boundaryTitle": "live 啟用邊界", + "metrics": { + "overall": "P2-108 進度", + "reports": "報告", + "agents": "Agent", + "charts": "圖表", + "workload": "工作量", + "done": "已完成", + "waitingApproval": "待審核", + "liveDelivery": "live 發送", + "liveOptimization": "live 優化" + }, + "flags": { + "daily": "日報可見: {value}", + "weekly": "週報可見: {value}", + "monthly": "月報可見: {value}", + "perAgent": "Agent 狀態可見: {value}", + "telegram": "Telegram 草案: {value}", + "scheduler": "scheduler: {value}", + "queue": "queue write: {value}", + "send": "Telegram send: {value}", + "analysis": "AI analysis: {value}", + "optimization": "production optimization: {value}", + "highApproval": "高風險人工審核: {value}" + }, + "labels": { + "completion": "完成度", + "reportDetail": "章節 {sections};圖表 {charts};工作量 {work};live {live}", + "workDone": "工作完成", + "agentDetail": "{done}/{total} 已完成;{approval} 待審核;24h live {live}", + "sections": "報告章節 {count}", + "recommendations": "分析建議 {count}" + }, + "answerStatuses": { + "complete": "已完成", + "guarded": "受閘門保護", + "next_gate": "下一關" + } + }, "reportRuntimeReadiness": { "title": "P2-403L 報表派送與自動處理啟動閘門", "source": "{generated} · {current} → {next}", diff --git a/apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx b/apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx index 18ceceb3b..66f72eee4 100644 --- a/apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx +++ b/apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx @@ -52,6 +52,7 @@ import { type AiAgentOwnerApprovedResultCaptureDryRunSnapshot, type AiAgentOwnerApprovedResultCaptureReadbackSnapshot, type AiAgentReportAutomationReviewSnapshot, + type AiAgentReportStatusBoardSnapshot, type AiAgentReportRuntimeDryRunSnapshot, type AiAgentReportRuntimeFixtureReadbackSnapshot, type AiAgentReportRuntimeReadinessSnapshot, @@ -421,6 +422,7 @@ export function AutomationInventoryTab() { const [postWriteVerifierPackage, setPostWriteVerifierPackage] = useState(null) const [runtimeVerifierEvidenceReview, setRuntimeVerifierEvidenceReview] = useState(null) const [reportAutomationReview, setReportAutomationReview] = useState(null) + const [reportStatusBoard, setReportStatusBoard] = useState(null) const [reportRuntimeReadiness, setReportRuntimeReadiness] = useState(null) const [reportRuntimeDryRun, setReportRuntimeDryRun] = useState(null) const [reportRuntimeFixtureReadback, setReportRuntimeFixtureReadback] = useState(null) @@ -465,6 +467,7 @@ export function AutomationInventoryTab() { apiClient.getAiAgentPostWriteVerifierPackage(), apiClient.getAiAgentRuntimeVerifierEvidenceReview(), apiClient.getAiAgentReportAutomationReview(), + apiClient.getAiAgentReportStatusBoard(), apiClient.getAiAgentReportRuntimeReadiness(), apiClient.getAiAgentReportRuntimeDryRun(), apiClient.getAiAgentReportRuntimeFixtureReadback(), @@ -508,6 +511,7 @@ export function AutomationInventoryTab() { postWriteVerifierPackageResult, runtimeVerifierEvidenceReviewResult, reportAutomationReviewResult, + reportStatusBoardResult, reportRuntimeReadinessResult, reportRuntimeDryRunResult, reportRuntimeFixtureReadbackResult, @@ -548,6 +552,7 @@ export function AutomationInventoryTab() { setPostWriteVerifierPackage(postWriteVerifierPackageResult.status === 'fulfilled' ? postWriteVerifierPackageResult.value : null) setRuntimeVerifierEvidenceReview(runtimeVerifierEvidenceReviewResult.status === 'fulfilled' ? runtimeVerifierEvidenceReviewResult.value : null) setReportAutomationReview(reportAutomationReviewResult.status === 'fulfilled' ? reportAutomationReviewResult.value : null) + setReportStatusBoard(reportStatusBoardResult.status === 'fulfilled' ? reportStatusBoardResult.value : null) setReportRuntimeReadiness(reportRuntimeReadinessResult.status === 'fulfilled' ? reportRuntimeReadinessResult.value : null) setReportRuntimeDryRun(reportRuntimeDryRunResult.status === 'fulfilled' ? reportRuntimeDryRunResult.value : null) setReportRuntimeFixtureReadback(reportRuntimeFixtureReadbackResult.status === 'fulfilled' ? reportRuntimeFixtureReadbackResult.value : null) @@ -586,6 +591,7 @@ export function AutomationInventoryTab() { postWriteVerifierPackageResult, runtimeVerifierEvidenceReviewResult, reportAutomationReviewResult, + reportStatusBoardResult, reportRuntimeReadinessResult, reportRuntimeDryRunResult, reportRuntimeFixtureReadbackResult, @@ -989,6 +995,11 @@ export function AutomationInventoryTab() { return reportAutomationReview.report_charts.slice(0, 4) }, [reportAutomationReview]) + const visibleReportStatusCharts = useMemo(() => { + if (!reportStatusBoard) return [] + return reportStatusBoard.visible_charts.slice(0, 3) + }, [reportStatusBoard]) + const visibleReportRecommendations = useMemo(() => { if (!reportAutomationReview) return [] const priority = { critical: 0, high: 0, medium: 1, low: 2 } as Record @@ -1692,7 +1703,7 @@ export function AutomationInventoryTab() { ) } - if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !proactiveOperations || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportAutomationReview || !reportRuntimeReadiness || !reportRuntimeDryRun || !reportRuntimeFixtureReadback || !runtimeWorkerShadowGate || !operationPermissionModel || !candidateOperationDryRunEvidence || !taskResultAuditTrail || !matchedPlaybookLearningGap || !criticReviewerResultCapture || !ownerApprovedResultCaptureDryRun || !ownerApprovedResultCaptureReadback || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { + if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !proactiveOperations || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportAutomationReview || !reportStatusBoard || !reportRuntimeReadiness || !reportRuntimeDryRun || !reportRuntimeFixtureReadback || !runtimeWorkerShadowGate || !operationPermissionModel || !candidateOperationDryRunEvidence || !taskResultAuditTrail || !matchedPlaybookLearningGap || !criticReviewerResultCapture || !ownerApprovedResultCaptureDryRun || !ownerApprovedResultCaptureReadback || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { return (
@@ -1842,6 +1853,15 @@ export function AutomationInventoryTab() { const reportAutoEnabled = reportAutomationReview.rollups.current_auto_execution_enabled_count const reportLiveDelivery = reportAutomationReview.rollups.live_report_delivery_count const reportLiveOptimization = reportAutomationReview.rollups.live_auto_optimization_count + const reportStatusOverall = reportStatusBoard.program_status.overall_completion_percent + const reportStatusCards = reportStatusBoard.rollups.report_card_count + const reportStatusAgents = reportStatusBoard.rollups.agent_status_count + const reportStatusCharts = reportStatusBoard.rollups.visible_chart_count + const reportStatusWorkload = reportStatusBoard.rollups.workload_unit_total + const reportStatusDone = reportStatusBoard.rollups.workload_done_total + const reportStatusWaitingApproval = reportStatusBoard.rollups.workload_waiting_approval_total + const reportStatusLiveDelivery = reportStatusBoard.rollups.live_delivery_count + const reportStatusLiveOptimization = reportStatusBoard.rollups.live_auto_optimization_count const reportRuntimeOverall = reportRuntimeReadiness.program_status.overall_completion_percent const reportRuntimeLanes = reportRuntimeReadiness.rollups.runtime_lane_count const reportRuntimeReady = reportRuntimeReadiness.rollups.ready_contract_count @@ -2780,6 +2800,179 @@ export function AutomationInventoryTab() {
+
+
+
+ + + {t('reportStatusBoard.title')} + +
+ +
+ +
+ } /> + } /> + } /> + } /> + } /> + } /> + 0 ? 'danger' : 'ok'} icon={} /> + } /> + } /> +
+ +
+
+ {t('reportStatusBoard.truthTitle')} + + {reportStatusBoard.report_completion_truth.truth_note} + +
+ + + + + +
+
+ +
+ {t('reportStatusBoard.boundaryTitle')} +
+ + + + + + +
+
+
+ +
+ {reportStatusBoard.report_status_cards.map(card => ( +
+
+ + {card.display_name} + + +
+ + + {card.next_gate} + +
+ ))} +
+ +
+ {reportStatusBoard.agent_status_reports.map(agent => { + const progress = agent.work_units_total > 0 ? Math.round((agent.work_units_done / agent.work_units_total) * 100) : 0 + return ( +
+
+ + {agent.display_name} + + +
+ + {agent.primary_role} + + = 85 ? 'ok' : 'warn'} + /> +
+ + + + + +
+ + {agent.status_note} + +
+ ) + })} +
+ +
+ {visibleReportStatusCharts.map(chart => { + const maxValue = Math.max(...chart.series.map(item => item.value), 1) + return ( +
+
+ + {chart.display_name} + + +
+
+ {chart.series.map(item => ( +
+ + {item.label} + +
+
+
+ + {item.value} + +
+ ))} +
+
+ ) + })} +
+ +
+ {reportStatusBoard.operator_answer_cards.map(answer => ( +
+
+ + {answer.question} + + +
+ + {answer.answer} + +
+ ))} +
+
+
diff --git a/apps/web/src/lib/api-client.ts b/apps/web/src/lib/api-client.ts index e9e9638f2..e960d44e8 100644 --- a/apps/web/src/lib/api-client.ts +++ b/apps/web/src/lib/api-client.ts @@ -380,6 +380,11 @@ export const apiClient = { return handleResponse(res) }, + async getAiAgentReportStatusBoard() { + const res = await fetch(`${API_BASE_URL}/agents/agent-report-status-board`) + return handleResponse(res) + }, + async getAiAgentReportRuntimeReadiness() { const res = await fetch(`${API_BASE_URL}/agents/agent-report-runtime-readiness`) return handleResponse(res) @@ -2182,6 +2187,115 @@ export interface AiAgentReportAutomationReviewSnapshot { } } +export interface AiAgentReportStatusBoardSnapshot { + schema_version: 'ai_agent_report_status_board_v1' + generated_at: string + program_status: { + overall_completion_percent: 100 + current_priority: 'P0' | 'P1' | 'P2' | 'P3' + current_task_id: 'P2-108' + next_task_id: string + read_only_mode: true + runtime_authority: 'report_status_board_only_no_live_send_or_write' + status_note: string + } + source_refs: string[] + report_completion_truth: { + daily_report_visible: true + weekly_report_visible: true + monthly_report_visible: true + per_agent_status_visible: true + workload_metrics_visible: true + chart_package_visible: true + telegram_digest_draft_visible: true + live_report_delivery_enabled: false + live_telegram_send_count_24h: number + ai_post_report_analysis_enabled: false + medium_low_auto_optimization_enabled: false + high_risk_human_approval_required: true + live_auto_optimization_count_24h: number + truth_note: string + } + report_status_cards: Array<{ + cadence_id: 'daily' | 'weekly' | 'monthly' + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + completion_percent: 100 + contract_state: 'visible_contract_ready' + delivery_state: 'draft_only' + sections_count: number + chart_count: number + work_units_total: number + live_delivery_count: number + next_gate: string + }> + agent_status_reports: Array<{ + agent_id: 'openclaw' | 'hermes' | 'nemotron' + display_name: string + primary_role: string + current_state: string + work_units_total: number + work_units_done: number + work_units_waiting_approval: number + report_sections_owned: number + analysis_recommendations_owned: number + live_runtime_work_units_24h: number + communication_state: string + learning_state: string + telegram_policy: string + status_note: string + }> + visible_charts: Array<{ + chart_id: string + display_name: string + chart_type: string + unit: string + series: Array<{ + label: string + value: number + tone: 'ok' | 'warn' | 'danger' | 'neutral' + }> + }> + operator_answer_cards: Array<{ + answer_id: string + question: string + answer: string + status: 'complete' | 'guarded' | 'next_gate' + }> + activation_boundaries: { + scheduler_enabled: false + gateway_queue_write_enabled: false + telegram_send_enabled: false + report_receipt_write_enabled: false + ai_analysis_run_enabled: false + medium_low_auto_execution_enabled: false + production_optimization_write_enabled: false + high_risk_requires_human_approval: true + } + display_redaction_contract: { + redaction_required: true + raw_prompt_display_allowed: false + private_reasoning_display_allowed: false + secret_value_display_allowed: false + internal_transcript_display_allowed: false + } + rollups: { + report_card_count: number + agent_status_count: number + visible_chart_count: number + operator_answer_count: number + completed_report_count: number + workload_unit_total: number + workload_done_total: number + workload_waiting_approval_total: number + live_delivery_count: number + live_telegram_send_count: number + live_runtime_work_units: number + live_auto_optimization_count: number + high_risk_requires_human_approval: true + } +} + export interface AiAgentReportRuntimeReadinessSnapshot { schema_version: 'ai_agent_report_runtime_readiness_v1' generated_at: string diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 1855ed22b..1e3da6fb3 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,30 @@ +## 2026-06-13|P2-108 日週月報與 Agent 工作狀態總覽本地完成 + +**背景**:統帥要求直接看到日報、週報、月報是否完成,以及 OpenClaw / Hermes / NemoTron 每個 Agent 做了哪些工作、工作量多少、目前能否自動發送或自動優化。 + +**完成內容**: +- 新增 `ai_agent_report_status_board_v1` schema、committed snapshot、loader 與 API endpoint `GET /api/v1/agents/agent-report-status-board`。 +- P2-108 snapshot 固定日報、週報、月報三張 report status card,三者可見完成度皆 `100%`;固定 3 個 Agent status report、3 張 chart 與 4 張統帥問答卡。 +- Governance automation inventory 頁新增 P2-108 區塊,顯示 P2-108 進度 `100%`、報告 `3`、Agent `3`、圖表 `3`、工作量 `91`、已完成 `79`、待審核 `12`、live 發送 `0`、live 優化 `0`。 +- 更新 MASTER、`docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md` 與 `docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md`,將下一步改為 `P2-109`。 + +**驗證**: +- JSON parse:P2-108 schema / snapshot、`zh-TW.json`、`en.json` 通過。 +- API/service pytest:P2-108、P2-403J 與 P2-107 目標組共 `26 passed`。 +- Web typecheck:以既有 pnpm 依賴臨時 symlink 執行 `pnpm --filter @awoooi/web typecheck` 通過;symlink 已移除。 + +**完成度同步**: +- P2-108:本地 `100%`。 +- AI Agent 自動化工作包:`94%`。 +- 報告可視化層:日報 / 週報 / 月報 / Agent 工作狀態 / 工作量 / 圖表 / 統帥問答已完成。 + +**安全邊界**: +- 本段仍是只讀狀態總覽;不排程實發、不寫 Gateway queue、不送 Telegram、不寫讀報回執、不啟動 AI analysis worker、不啟動中低風險 auto worker、不執行 production optimization、不讀 secret、不顯示內部協作內容。 +- live report delivery、Telegram send、runtime work units、auto optimization 全部維持 `0`。 + +**下一步**: +- `P2-109`:report live delivery approval package,先固定 scheduler / Telegram receipt / owner approval / rollback / failure-only notification gate;未通過前不得啟用 live send 或 live write。 + ## 2026-06-13|Reboot SOP final goal audit refresh **背景**:接續 120 fsck 恢復、backup/offsite convergence、API/Web workload balancing、security mirror deploy closeout 與 P2-107 正式驗證後,重新做一次只讀 final gate audit,確認重啟 SOP 的第一屏狀態與 live runtime 一致。 diff --git a/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md b/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md index f4cf63625..88ba98322 100644 --- a/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md +++ b/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md @@ -12,17 +12,17 @@ | Nemotron 實際整合應用 | 30% | 完整回放前仍被關卡擋下 | `blocked_needs_evidence`,下一關是 `refresh_source_evidence_then_5_record_smoke_only` | | 工具 / 服務 / 套件 AI 自動化 | 92% | P0 已完成;P1 服務 / runtime / 監控 / provider / service health / 備份 / DR / 套件與供應鏈只讀基線已完成;P1-007 失敗限定通知合約與前端 redaction 合約已完成;下一主線是 P2-004 依賴 / 供應鏈漂移監控 | 狀態分類、盤點 schema、權限矩陣、靜態盤點種子、只讀 API、UI 骨架、驗證、自動化待辦 schema / 快照 / API / 分組 UI、Backup / DR 目標盤點、準備度矩陣、備份通知政策、Backup / DR 證據 UI、復原演練批准包模板、異地 / escrow 準備度狀態、任務批准邊界、確定性進度彙總、Python 套件 / 供應鏈只讀基線、JS pnpm/npm 只讀基線、Docker build surface 只讀基線、CVE / license / drift 嚴重度政策、定期依賴漂移與外部資料來源檢查設計、依賴升級批准包模板、runtime_surface_inventory_v1 schema / snapshot / API / UI、gitea_workflow_runner_health_v1 schema / snapshot / API / UI、observability_contract_matrix_v1 schema / snapshot / API / UI、ai_provider_route_matrix_v1 schema / snapshot / API / UI、service_health_gap_matrix_v1 schema / snapshot / API / UI、service health evidence cards UI、service_health_failure_notification_policy_v1 schema / snapshot / API / UI 已完成 | | OpenClaw / Hermes / NemoTron 佈建布局 | 45% | P1-401 / P1-402 已完成;仍是只讀 layout 與治理頁顯示,不是 runtime deploy | `ai_agent_deployment_layout_v1` schema、`ai_agent_deployment_layout_2026-06-11.json`、`GET /api/v1/agents/agent-deployment-layout`、治理頁自動化盤點 UI、`AI_AGENT_DEPLOYMENT_LAYOUT_2026-06-11.md` | -| OpenClaw / Hermes / NemoTron 主動溝通、學習與成長證據 | 100% | P2-401A 已完成只讀 contract;P2-403A 已完成互動 / 接手 / 學習 / 成長證據面板;P2-403B 已完成 AgentSession / Redis Streams live read model gate;P2-403C 已完成 Redis Streams consumer group dry-run、handoff envelope、ack / dead-letter / replay gate;P2-403D 已完成 learning writeback approval package;P2-403E 已完成 Telegram receipt approval package;P2-403F 已完成 owner-approved learning dry-run preview、人工操作選項與 fixture-only dry-run 總包;P2-403G 已完成 runtime write gate review;P2-403H 已完成 post-write verifier implementation package;P2-403I 已完成 runtime verifier evidence implementation review;P2-403J 已完成報表真相 / 告警有效性 / 日週月報 / Agent 工作量 / 圖表化報告 / AI 建議 / 風險自動化政策審查;P2-403K / L / M / N 已把 SRE 戰情室路由、報表派送啟動前閘門、no-write dry-run 與 fixture/readback/verifier dry-run 固定;P2-404 已完成 runtime worker shadow / no-write evidence;P2-101 已完成操作類別權限模型;P2-102 已完成 13 類候選操作 dry-run 證據;P2-103 已完成任務結果稽核軌跡;P2-104 已完成 matched PlayBook 學習缺口回查;P2-105 已完成 critic / reviewer 評分與 result capture 契約;P2-106 已完成 owner-approved result capture dry-run;P2-107 已完成 owner-approved result capture readback / promotion readiness,固定 5 個 readback digest、5 個 promotion review、4 條 failure lane、4 個 reviewer queue preview 與 5 個 operator action,正式站 deploy marker `834ccdba` 已驗證 API / UI。runtime worker、DB migration、production Redis consumer group、canonical runtime readback、runtime score、result capture write、Telegram 實發、delivery receipt E2E、report delivery、reviewer queue write、Gateway queue write、AI analysis runtime、中低風險 auto worker、KM / LOGBOOK / audit DB / timeline / PlayBook trust 寫入、SDK / 付費服務仍未開 gate | `ai_agent_communication_learning_contract_v1`、`ai_agent_interaction_learning_proof_v1`、`ai_agent_operation_permission_model_v1`、`ai_agent_candidate_operation_dry_run_evidence_v1`、`ai_agent_task_result_audit_trail_v1`、`ai_agent_matched_playbook_learning_gap_v1`、`ai_agent_critic_reviewer_result_capture_v1`、`ai_agent_owner_approved_result_capture_dry_run_v1`、`ai_agent_owner_approved_result_capture_readback_v1`、`GET /api/v1/agents/agent-operation-permission-model`、`GET /api/v1/agents/agent-candidate-operation-dry-run-evidence`、`GET /api/v1/agents/agent-task-result-audit-trail`、`GET /api/v1/agents/agent-matched-playbook-learning-gap`、`GET /api/v1/agents/agent-critic-reviewer-result-capture`、`GET /api/v1/agents/agent-owner-approved-result-capture-dry-run`、`GET /api/v1/agents/agent-owner-approved-result-capture-readback`、`/zh-TW/governance?tab=automation-inventory`、MASTER §3.2.1b / §3.2.1d / §3.4.3 | +| OpenClaw / Hermes / NemoTron 主動溝通、學習與成長證據 | 100% | P2-401A 已完成只讀 contract;P2-403A 已完成互動 / 接手 / 學習 / 成長證據面板;P2-403B 已完成 AgentSession / Redis Streams live read model gate;P2-403C 已完成 Redis Streams consumer group dry-run、handoff envelope、ack / dead-letter / replay gate;P2-403D 已完成 learning writeback approval package;P2-403E 已完成 Telegram receipt approval package;P2-403F 已完成 owner-approved learning dry-run preview、人工操作選項與 fixture-only dry-run 總包;P2-403G 已完成 runtime write gate review;P2-403H 已完成 post-write verifier implementation package;P2-403I 已完成 runtime verifier evidence implementation review;P2-403J 已完成報表真相 / 告警有效性 / 日週月報 / Agent 工作量 / 圖表化報告 / AI 建議 / 風險自動化政策審查;P2-403K / L / M / N 已把 SRE 戰情室路由、報表派送啟動前閘門、no-write dry-run 與 fixture/readback/verifier dry-run 固定;P2-404 已完成 runtime worker shadow / no-write evidence;P2-101 已完成操作類別權限模型;P2-102 已完成 13 類候選操作 dry-run 證據;P2-103 已完成任務結果稽核軌跡;P2-104 已完成 matched PlayBook 學習缺口回查;P2-105 已完成 critic / reviewer 評分與 result capture 契約;P2-106 已完成 owner-approved result capture dry-run;P2-107 已完成 owner-approved result capture readback / promotion readiness;P2-108 已完成日週月報與 Agent 工作狀態總覽,三種報告可見完成度皆 `100%`,3 個 Agent 狀態報告、3 張圖表、4 張統帥問答卡、工作量 `91`、已完成 `79`、待審核 `12`。runtime worker、DB migration、production Redis consumer group、canonical runtime readback、runtime score、result capture write、Telegram 實發、delivery receipt E2E、report delivery、reviewer queue write、Gateway queue write、AI analysis runtime、中低風險 auto worker、KM / LOGBOOK / audit DB / timeline / PlayBook trust 寫入、SDK / 付費服務仍未開 gate | `ai_agent_communication_learning_contract_v1`、`ai_agent_interaction_learning_proof_v1`、`ai_agent_operation_permission_model_v1`、`ai_agent_candidate_operation_dry_run_evidence_v1`、`ai_agent_task_result_audit_trail_v1`、`ai_agent_matched_playbook_learning_gap_v1`、`ai_agent_critic_reviewer_result_capture_v1`、`ai_agent_owner_approved_result_capture_dry_run_v1`、`ai_agent_owner_approved_result_capture_readback_v1`、`ai_agent_report_status_board_v1`、`GET /api/v1/agents/agent-operation-permission-model`、`GET /api/v1/agents/agent-candidate-operation-dry-run-evidence`、`GET /api/v1/agents/agent-task-result-audit-trail`、`GET /api/v1/agents/agent-matched-playbook-learning-gap`、`GET /api/v1/agents/agent-critic-reviewer-result-capture`、`GET /api/v1/agents/agent-owner-approved-result-capture-dry-run`、`GET /api/v1/agents/agent-owner-approved-result-capture-readback`、`GET /api/v1/agents/agent-report-status-board`、`/zh-TW/governance?tab=automation-inventory`、MASTER §3.2.1b / §3.2.1d / §3.4.3 | | AI Agent 主動營運委派與版本生命週期 | 100% | P2-402A / P2-402B / P2-402C / P2-402D / P2-402E / P2-402F / P2-402G 已完成;已建立 repo-only 版本新鮮度快照、工具採用批准包、Telegram action-required digest policy、Gitea PR 草案 lane、host / K3s / stateful 版本只讀盤點、API 與 governance UI。定期排程、外部版本查詢、工具安裝、CI 變更、套件升級、主機更新、container pull、實際 PR creation、auto merge、Telegram 實發、SSH、kubectl、重啟仍未開 gate | `ai_agent_proactive_operations_contract_v1`、`ai_agent_version_freshness_snapshot_v1`、`ai_agent_tool_adoption_approval_package_v1`、`ai_agent_telegram_action_required_digest_policy_v1`、`ai_agent_gitea_pr_draft_lane_v1`、`ai_agent_host_stateful_version_inventory_v1`、`GET /api/v1/agents/agent-proactive-operations-contract`、`GET /api/v1/agents/agent-version-freshness-snapshot`、`GET /api/v1/agents/agent-tool-adoption-approval-package`、`GET /api/v1/agents/agent-telegram-action-required-digest-policy`、`GET /api/v1/agents/agent-gitea-pr-draft-lane`、`GET /api/v1/agents/agent-host-stateful-version-inventory`、`/zh-TW/governance?tab=automation-inventory`、MASTER §3.2.1c | | 本工作清單與分析報告 | 100% | 已完成 | 本 MD 文件 | -AI Agent 自動化工作包目前完成度:**93%**。本工作清單文件本身完成度:**100%**。 +AI Agent 自動化工作包目前完成度:**94%**。本工作清單文件本身完成度:**100%**。 三 Agent 佈建布局目前完成度:**45%**。第一波已完成只讀 schema / snapshot / API / 測試 / 報告,第二波已接入治理頁自動化盤點 UI;正式 runtime 佈署、Telegram E2E 發送與 AgentSession 工作流仍需逐項 gate。 -三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。已完成只讀契約、互動 / 接手 / 學習 / 成長證據面板、P2-403B live read model gate、P2-403C Redis dry-run gate、P2-403D learning writeback approval package、P2-403E Telegram receipt approval package、P2-403F owner-approved learning dry-run preview、P2-403G runtime write gate review、P2-403H post-write verifier implementation package、P2-403I runtime verifier evidence implementation review、P2-403J 報表真相 / 告警有效性 / 日週月報 / Agent 工作量 / 圖表化報告 / AI 建議 / 風險自動化政策審查、P2-403K/L/M/N 報表與 SRE 戰情室 dry-run 鏈、P2-404 runtime worker shadow / no-write execution evidence gate、P2-101 操作類別權限模型、P2-102 候選操作 dry-run 證據、P2-103 任務結果稽核軌跡、P2-104 matched PlayBook 學習缺口回查、P2-105 critic / reviewer 評分與 result capture 契約、P2-106 owner-approved result capture dry-run,以及 P2-107 owner-approved result capture readback / promotion readiness;P2-107 正式站已由 deploy marker `834ccdba` 驗證 API / UI。目前 live AgentSession、Agent message、handoff、canonical runtime readback、runtime score、result capture write、learning write、Telegram receipt、Gateway queue write、reviewer queue write、runtime verifier execution、report delivery、AI analysis runtime、中低風險 auto worker、Telegram 實發、shadow worker live、delivery receipt E2E、KM / LOGBOOK / audit DB / timeline / PlayBook trust runtime 寫入仍全部為 `0`。P2-107 已固定 5 個 readback digest、5 個 promotion review、4 條 failure lane、4 個 reviewer queue preview 與 5 個 operator action;真正下一步是 `P2-108`。 +三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。已完成只讀契約、互動 / 接手 / 學習 / 成長證據面板、P2-403B live read model gate、P2-403C Redis dry-run gate、P2-403D learning writeback approval package、P2-403E Telegram receipt approval package、P2-403F owner-approved learning dry-run preview、P2-403G runtime write gate review、P2-403H post-write verifier implementation package、P2-403I runtime verifier evidence implementation review、P2-403J 報表真相 / 告警有效性 / 日週月報 / Agent 工作量 / 圖表化報告 / AI 建議 / 風險自動化政策審查、P2-403K/L/M/N 報表與 SRE 戰情室 dry-run 鏈、P2-404 runtime worker shadow / no-write execution evidence gate、P2-101 操作類別權限模型、P2-102 候選操作 dry-run 證據、P2-103 任務結果稽核軌跡、P2-104 matched PlayBook 學習缺口回查、P2-105 critic / reviewer 評分與 result capture 契約、P2-106 owner-approved result capture dry-run、P2-107 owner-approved result capture readback / promotion readiness,以及 P2-108 日週月報與 Agent 工作狀態總覽。目前 live AgentSession、Agent message、handoff、canonical runtime readback、runtime score、result capture write、learning write、Telegram receipt、Gateway queue write、reviewer queue write、runtime verifier execution、report delivery、AI analysis runtime、中低風險 auto worker、Telegram 實發、shadow worker live、delivery receipt E2E、KM / LOGBOOK / audit DB / timeline / PlayBook trust runtime 寫入仍全部為 `0`。P2-108 已固定三種報告 `100%` 可見、3 個 Agent 狀態報告、3 張圖表與 4 張統帥問答卡;真正下一步是 `P2-109`。 -AI Agent 主動營運委派與版本生命週期目前完成度:**100%**。已完成 12 類版本 domain、24 類可委派能力、5 種 cadence、8 類 MCP、4 類 RAG memory、只讀 API、`P2-402B` repo-only daily version freshness snapshot、`P2-402C` Renovate / OSV-Scanner / Trivy / Syft / Grype 工具採用批准包、`P2-402D` Telegram action-required digest policy、`P2-402E` Gitea PR 草案 lane、`P2-402F` host OS / K3s / stateful services 版本只讀盤點,以及 `P2-402G` governance UI 顯示可委派能力;`P2-403A` 到 `P2-107` 已補互動、學習證據面、live read model gate、Redis dry-run gate、learning writeback approval package、Telegram receipt approval package、owner-approved learning dry-run preview、runtime write gate review、post-write verifier package、runtime verifier evidence review、報表真相、TG 戰情室收斂、日週月報、Agent 工作量、圖表化報告、風險自動化政策、報表 runtime 啟動前閘門、no-write dry-run 證據包、fixture/readback/verifier dry-run 證據包、shadow/no-write execution gate、操作類別權限模型、13 類候選操作 dry-run 證據、任務結果稽核軌跡、matched PlayBook 學習缺口、critic / reviewer result capture、owner-approved result capture dry-run 與 owner-approved result capture readback / promotion readiness。下一步是 `P2-108`;外部 registry / package source / host probe / SSH / kubectl / 工具安裝 / CI 變更 / 實際 PR creation / Telegram 實發與 learning write 仍需 gate。 +AI Agent 主動營運委派與版本生命週期目前完成度:**100%**。已完成 12 類版本 domain、24 類可委派能力、5 種 cadence、8 類 MCP、4 類 RAG memory、只讀 API、`P2-402B` repo-only daily version freshness snapshot、`P2-402C` Renovate / OSV-Scanner / Trivy / Syft / Grype 工具採用批准包、`P2-402D` Telegram action-required digest policy、`P2-402E` Gitea PR 草案 lane、`P2-402F` host OS / K3s / stateful services 版本只讀盤點,以及 `P2-402G` governance UI 顯示可委派能力;`P2-403A` 到 `P2-108` 已補互動、學習證據面、live read model gate、Redis dry-run gate、learning writeback approval package、Telegram receipt approval package、owner-approved learning dry-run preview、runtime write gate review、post-write verifier package、runtime verifier evidence review、報表真相、TG 戰情室收斂、日週月報、Agent 工作量、圖表化報告、風險自動化政策、報表 runtime 啟動前閘門、no-write dry-run 證據包、fixture/readback/verifier dry-run 證據包、shadow/no-write execution gate、操作類別權限模型、13 類候選操作 dry-run 證據、任務結果稽核軌跡、matched PlayBook 學習缺口、critic / reviewer result capture、owner-approved result capture dry-run、owner-approved result capture readback / promotion readiness 與 Agent report status board。下一步是 `P2-109`;外部 registry / package source / host probe / SSH / kubectl / 工具安裝 / CI 變更 / 實際 PR creation / Telegram 實發與 learning write 仍需 gate。 完成度計算模型: diff --git a/docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md b/docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md index ed483a921..3b2368475 100644 --- a/docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md +++ b/docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md @@ -1,8 +1,8 @@ # AI Agent 互動、溝通、學習與成長證據報告 > 日期:2026-06-11(台北時間) -> 文件定位:P2-403A 證據面 + P2-403B AgentSession / Redis Streams live read model gate + P2-403C Redis dry-run gate + P2-403D learning writeback approval package + P2-403E Telegram receipt approval package + P2-403F owner-approved learning dry-run / fixture dry-run、P2-403G runtime write gate review、P2-403H post-write verifier package、P2-403I runtime verifier evidence implementation review、P2-403J 報表真相 / 日週月報 / Agent 工作量 / 風險自動化 review、P2-403L 報表派送與自動處理啟動前閘門、P2-403M 報表 runtime no-write dry-run 證據包、P2-403N fixture smoke / queue preview readback / verifier dry-run、P2-404 runtime worker shadow / no-write execution evidence gate、P2-101 操作類別權限模型、P2-102 候選操作 dry-run 證據、P2-103 任務結果稽核軌跡、P2-104 matched PlayBook 學習缺口、P2-105 critic / reviewer 評分與 result capture、API 與治理頁 UI。 -> 事實邊界:本波只建立可見證據面、read model gate、報表治理 review、runtime readiness gate、no-write dry-run、fixture/readback/verifier dry-run、shadow/no-write execution 證據包、operation permission lane、candidate dry-run evidence、result audit trail、matched PlayBook learning gap readback 與 critic / reviewer result capture gate,不啟動 runtime worker、不建立 DB migration、不開 Redis consumer group、不發 Telegram、不寫 Gateway queue、不寫 delivery receipt、不排程實發報告、不啟動中低風險 auto worker、不執行 verifier live readback、不寫 KM、不 runtime append LOGBOOK、不寫 audit DB、不寫 timeline、不更新 PlayBook trust、不執行生產優化、不顯示內部協作內容。 +> 文件定位:P2-403A 證據面 + P2-403B AgentSession / Redis Streams live read model gate + P2-403C Redis dry-run gate + P2-403D learning writeback approval package + P2-403E Telegram receipt approval package + P2-403F owner-approved learning dry-run / fixture dry-run、P2-403G runtime write gate review、P2-403H post-write verifier package、P2-403I runtime verifier evidence implementation review、P2-403J 報表真相 / 日週月報 / Agent 工作量 / 風險自動化 review、P2-403L 報表派送與自動處理啟動前閘門、P2-403M 報表 runtime no-write dry-run 證據包、P2-403N fixture smoke / queue preview readback / verifier dry-run、P2-404 runtime worker shadow / no-write execution evidence gate、P2-101 操作類別權限模型、P2-102 候選操作 dry-run 證據、P2-103 任務結果稽核軌跡、P2-104 matched PlayBook 學習缺口、P2-105 critic / reviewer 評分與 result capture、P2-106 / P2-107 owner-approved result capture dry-run / readback、P2-108 日週月報與 Agent 工作狀態總覽、API 與治理頁 UI。 +> 事實邊界:本波只建立可見證據面、read model gate、報表治理 review、runtime readiness gate、no-write dry-run、fixture/readback/verifier dry-run、shadow/no-write execution 證據包、operation permission lane、candidate dry-run evidence、result audit trail、matched PlayBook learning gap readback、critic / reviewer result capture gate 與 report status board,不啟動 runtime worker、不建立 DB migration、不開 Redis consumer group、不發 Telegram、不寫 Gateway queue、不寫 delivery receipt、不排程實發報告、不啟動中低風險 auto worker、不執行 verifier live readback、不寫 KM、不 runtime append LOGBOOK、不寫 audit DB、不寫 timeline、不更新 PlayBook trust、不執行生產優化、不顯示內部協作內容。 ## 0. P2-403J 補記:報表真相、日週月報與風險自動化 Review @@ -66,7 +66,7 @@ ## 1. 結論 -已完成 P2-403A、P2-403B、P2-403C、P2-403D、P2-403E、P2-403F、P2-403G、P2-403H、P2-403I、P2-403J、P2-403L、P2-403M、P2-403N、P2-404、P2-101、P2-102、P2-103、P2-104 與 P2-105:讓統帥能在治理頁看到 OpenClaw / Hermes / NemoTron 的互動、接手、學習與成長是否真的有證據,並看到 live read model、Redis dry-run、handoff envelope、ack / dead-letter / replay、learning writeback approval、Telegram receipt approval、fixture dry-run、runtime write gate review、post-write verifier package、runtime verifier evidence review、報表真相、日週月報、Agent 工作量、圖表化報告、風險自動化政策、報表 runtime 啟動前閘門、no-write dry-run 證據包、fixture/readback/verifier dry-run 證據包、shadow/no-write execution evidence gate、操作類別權限模型、候選操作 dry-run 證據、任務結果稽核軌跡、matched PlayBook 學習缺口與 critic / reviewer result capture gate。 +已完成 P2-403A、P2-403B、P2-403C、P2-403D、P2-403E、P2-403F、P2-403G、P2-403H、P2-403I、P2-403J、P2-403L、P2-403M、P2-403N、P2-404、P2-101、P2-102、P2-103、P2-104、P2-105、P2-106、P2-107 與 P2-108:讓統帥能在治理頁看到 OpenClaw / Hermes / NemoTron 的互動、接手、學習與成長是否真的有證據,並看到 live read model、Redis dry-run、handoff envelope、ack / dead-letter / replay、learning writeback approval、Telegram receipt approval、fixture dry-run、runtime write gate review、post-write verifier package、runtime verifier evidence review、報表真相、日週月報、Agent 工作量、圖表化報告、風險自動化政策、報表 runtime 啟動前閘門、no-write dry-run 證據包、fixture/readback/verifier dry-run 證據包、shadow/no-write execution evidence gate、操作類別權限模型、候選操作 dry-run 證據、任務結果稽核軌跡、matched PlayBook 學習缺口、critic / reviewer result capture gate、owner-approved result capture dry-run / readback 與日週月報工作狀態總覽。 目前真相: @@ -94,6 +94,7 @@ | P2-103 task result audit trail | 已完成,8 條結果路由已接到 KM 草稿、LOGBOOK 證據、audit trail、timeline 與人工交接契約,所有 KM / LOGBOOK / audit / timeline / queue / send 寫入全為 `0` | | P2-104 matched PlayBook learning gap | 已完成,正式 DB 只讀回查確認 24h matched `66/66`,active gap 是 APPROVED `63` 筆缺 execution learning、PlayBook updated_24h `0` | | P2-105 critic / reviewer result capture | 已完成,5 張 scorecard、5 個 result capture contract、6 個 promotion gate、4 條 candidate route;runtime score / capture / learning / trust / queue / send 全為 `0` | +| P2-108 report status board | 已完成,日報 / 週報 / 月報 `100%` 可見、3 個 Agent 狀態報告、3 張圖表、4 張統帥問答卡;live delivery / Telegram send / runtime work / auto optimization 全為 `0` | 這代表使用者現在可以看見「哪裡已準備好、哪裡仍未運作、被哪個 gate 阻擋、下一步要如何驗證」。但還不能宣稱三個 Agent 已經在 production runtime 主動互傳訊息或自主學習。 @@ -173,18 +174,20 @@ | `docs/evaluations/ai_agent_owner_approved_result_capture_dry_run_2026-06-13.json` | P2-106 committed snapshot,完成度 `100%`,5 個 no-write result capture template、5 個 score fixture、7 個 dry-run gate、5 個 operator action;所有 live write / send counts 全為 `0` | | `docs/schemas/ai_agent_owner_approved_result_capture_readback_v1.schema.json` | P2-107 owner-approved result capture readback schema;強制 canonical runtime readback、promotion approved、reviewer queue write、score write、result capture write、learning write、PlayBook trust write、Gateway queue、Telegram、production write、secret read 與 destructive action 維持未授權 | | `docs/evaluations/ai_agent_owner_approved_result_capture_readback_2026-06-13.json` | P2-107 committed snapshot,完成度 `100%`,5 個 readback digest、5 個 promotion review、4 條 failure lane、4 個 reviewer queue preview、5 個 operator action;canonical runtime readback、promotion approved、reviewer queue write 與所有 live write / send counts 全為 `0` | +| `docs/schemas/ai_agent_report_status_board_v1.schema.json` | P2-108 日週月報與 Agent 工作狀態總覽 schema;強制報告 / Agent 狀態 / 圖表可見,但 scheduler、Gateway queue、Telegram send、AI analysis 與 production optimization 維持未啟用 | +| `docs/evaluations/ai_agent_report_status_board_2026-06-13.json` | P2-108 committed snapshot,完成度 `100%`,日報 / 週報 / 月報 `100%` 可見、3 個 Agent 狀態報告、3 張圖表、4 張統帥問答卡;live delivery / Telegram send / runtime work / auto optimization 全為 `0` | | `GET /api/v1/agents/agent-critic-reviewer-result-capture` | 只讀 API;不寫 score、不寫 result capture、不寫 learning、不更新 PlayBook trust、不送 Telegram | | `apps/api/src/services/ai_agent_interaction_learning_proof.py` | 只讀 loader 與安全驗證 | | `apps/api/src/services/ai_agent_live_read_model_gate.py` | P2-403B 只讀 loader;拒絕 live DB query、Redis consumer、unsafe fields、Telegram 與 writeback | | `GET /api/v1/agents/agent-interaction-learning-proof` | 只讀 API,不啟動 worker、不碰 Redis / DB runtime、不發 Telegram | | `GET /api/v1/agents/agent-live-read-model-gate` | 只讀 API,不連 DB、不讀寫 Redis、不發 Telegram | -| governance UI | 新增證據階梯、目前真相、P2-403B live read gate、P2-403C Redis dry-run gate、P2-403D learning writeback approval package、P2-403E Telegram receipt approval package、P2-403F owner-approved learning dry-run / fixture dry-run、P2-403G runtime write gate review、P2-403H post-write verifier package、P2-403I runtime verifier evidence review、P2-403J 報表真相 / 日週月報 / Agent 工作量 / 圖表 / AI 建議、P2-403L 報表 runtime readiness、P2-403M no-write dry-run、P2-403N fixture readback、P2-404 shadow gate、P2-101 operation permission model、P2-102 candidate dry-run evidence、P2-103 task result audit trail、P2-104 matched PlayBook learning gap、P2-105 critic / reviewer result capture、P2-106 owner-approved result capture dry-run、P2-107 owner-approved result capture readback / promotion readiness、Agent lane、可觀測訊號、runtime gates、前端 redaction | +| governance UI | 新增證據階梯、目前真相、P2-403B live read gate、P2-403C Redis dry-run gate、P2-403D learning writeback approval package、P2-403E Telegram receipt approval package、P2-403F owner-approved learning dry-run / fixture dry-run、P2-403G runtime write gate review、P2-403H post-write verifier package、P2-403I runtime verifier evidence review、P2-403J 報表真相 / 日週月報 / Agent 工作量 / 圖表 / AI 建議、P2-108 日週月報與 Agent 工作狀態總覽、P2-403L 報表 runtime readiness、P2-403M no-write dry-run、P2-403N fixture readback、P2-404 shadow gate、P2-101 operation permission model、P2-102 candidate dry-run evidence、P2-103 task result audit trail、P2-104 matched PlayBook learning gap、P2-105 critic / reviewer result capture、P2-106 owner-approved result capture dry-run、P2-107 owner-approved result capture readback / promotion readiness、Agent lane、可觀測訊號、runtime gates、前端 redaction | ## 5. 後續優先順序 | 優先 | ID | 工作 | gate | |---:|---|---|---| -| 1 | P2-108 | runtime readback approval package | 以 P2-107 readback / promotion readiness 產生下一關批准包,仍需維持 no live write | +| 1 | P2-109 | report live delivery approval package | 以 P2-108 report status board 產生下一關批准包,仍需維持 no live send / no live write | ## 6. 紅線 diff --git a/docs/evaluations/ai_agent_report_status_board_2026-06-13.json b/docs/evaluations/ai_agent_report_status_board_2026-06-13.json new file mode 100644 index 000000000..2006d30cb --- /dev/null +++ b/docs/evaluations/ai_agent_report_status_board_2026-06-13.json @@ -0,0 +1,222 @@ +{ + "schema_version": "ai_agent_report_status_board_v1", + "generated_at": "2026-06-13T15:08:00+08:00", + "program_status": { + "overall_completion_percent": 100, + "current_priority": "P2", + "current_task_id": "P2-108", + "next_task_id": "P2-109", + "read_only_mode": true, + "runtime_authority": "report_status_board_only_no_live_send_or_write", + "status_note": "P2-108 將日報、週報、月報完成狀態、每個 AI Agent 工作狀態、工作量、圖表與 Telegram / 自動優化邊界收斂成治理頁可見總覽;此快照只讀,不排程、不送 Telegram、不寫 Gateway queue、不啟動 AI 自動優化。" + }, + "source_refs": [ + "docs/evaluations/ai_agent_report_automation_review_2026-06-12.json", + "docs/evaluations/ai_agent_report_runtime_readiness_2026-06-12.json", + "docs/evaluations/ai_agent_report_runtime_dry_run_2026-06-12.json", + "docs/evaluations/ai_agent_report_runtime_fixture_readback_2026-06-12.json", + "docs/evaluations/ai_agent_owner_approved_result_capture_readback_2026-06-13.json", + "docs/schemas/ai_agent_report_status_board_v1.schema.json" + ], + "report_completion_truth": { + "daily_report_visible": true, + "weekly_report_visible": true, + "monthly_report_visible": true, + "per_agent_status_visible": true, + "workload_metrics_visible": true, + "chart_package_visible": true, + "telegram_digest_draft_visible": true, + "live_report_delivery_enabled": false, + "live_telegram_send_count_24h": 0, + "ai_post_report_analysis_enabled": false, + "medium_low_auto_optimization_enabled": false, + "high_risk_human_approval_required": true, + "live_auto_optimization_count_24h": 0, + "truth_note": "報告可視化層已完成:治理頁可直接看到日報、週報、月報、每個 Agent 工作量與圖表。runtime 層尚未允許自動實發、讀報後自動分析或生產優化,因此 live 發送與 live 優化計數保持 0。" + }, + "report_status_cards": [ + { + "cadence_id": "daily", + "display_name": "AI Agent 日報", + "owner_agent": "hermes", + "completion_percent": 100, + "contract_state": "visible_contract_ready", + "delivery_state": "draft_only", + "sections_count": 6, + "chart_count": 3, + "work_units_total": 24, + "live_delivery_count": 0, + "next_gate": "P2-109 啟用前需通過 Telegram receipt 與 scheduler no-write readback。" + }, + { + "cadence_id": "weekly", + "display_name": "AI Agent 週報", + "owner_agent": "openclaw", + "completion_percent": 100, + "contract_state": "visible_contract_ready", + "delivery_state": "draft_only", + "sections_count": 6, + "chart_count": 4, + "work_units_total": 34, + "live_delivery_count": 0, + "next_gate": "P2-109 必須先處理 all-zero weekly report confidence 與 actionability gate。" + }, + { + "cadence_id": "monthly", + "display_name": "AI Agent 月報", + "owner_agent": "openclaw", + "completion_percent": 100, + "contract_state": "visible_contract_ready", + "delivery_state": "draft_only", + "sections_count": 6, + "chart_count": 4, + "work_units_total": 33, + "live_delivery_count": 0, + "next_gate": "P2-109 需接市場技術 watch、成本效益與統帥月度審核包。" + } + ], + "agent_status_reports": [ + { + "agent_id": "openclaw", + "display_name": "OpenClaw", + "primary_role": "生產仲裁、風險決策、HITL 關卡、runtime write / verifier 前後審查。", + "current_state": "visible_contract_ready", + "work_units_total": 38, + "work_units_done": 32, + "work_units_waiting_approval": 6, + "report_sections_owned": 5, + "analysis_recommendations_owned": 4, + "live_runtime_work_units_24h": 0, + "communication_state": "recorded_in_fixture", + "learning_state": "read_only_evidence", + "telegram_policy": "owner_review_packet_only", + "status_note": "OpenClaw 的工作狀態與工作量已在治理頁可見;高風險與 promotion 仍需要人工批准後才可進 runtime write。" + }, + { + "agent_id": "hermes", + "display_name": "Hermes", + "primary_role": "治理、文件、KM、套件與供應鏈、版本盤點、降噪、日報彙整。", + "current_state": "visible_contract_ready", + "work_units_total": 45, + "work_units_done": 42, + "work_units_waiting_approval": 3, + "report_sections_owned": 7, + "analysis_recommendations_owned": 4, + "live_runtime_work_units_24h": 0, + "communication_state": "recorded_in_fixture", + "learning_state": "read_only_evidence", + "telegram_policy": "daily_digest_draft_only", + "status_note": "Hermes 已負責日報與治理彙整的可視化;仍不得直接寫 KM canonical、修改 workflow 或實發 Telegram。" + }, + { + "agent_id": "nemotron", + "display_name": "NemoTron", + "primary_role": "離線模型評估、sanitized replay、regression fixture、長任務能力驗證。", + "current_state": "offline_evaluation_ready", + "work_units_total": 8, + "work_units_done": 5, + "work_units_waiting_approval": 3, + "report_sections_owned": 3, + "analysis_recommendations_owned": 2, + "live_runtime_work_units_24h": 0, + "communication_state": "recorded_in_fixture", + "learning_state": "read_only_evaluation", + "telegram_policy": "no_direct_notify", + "status_note": "NemoTron 工作狀態已可見;目前角色仍是離線 replay / evaluation,不是 live writer。" + } + ], + "visible_charts": [ + { + "chart_id": "report_cadence_completion", + "display_name": "日週月報完成度", + "chart_type": "bar", + "unit": "percent", + "series": [ + { "label": "日報", "value": 100, "tone": "ok" }, + { "label": "週報", "value": 100, "tone": "ok" }, + { "label": "月報", "value": 100, "tone": "ok" } + ] + }, + { + "chart_id": "agent_workload_status", + "display_name": "每個 Agent 工作量", + "chart_type": "bar", + "unit": "work_units", + "series": [ + { "label": "OpenClaw", "value": 38, "tone": "warn" }, + { "label": "Hermes", "value": 45, "tone": "ok" }, + { "label": "NemoTron", "value": 8, "tone": "neutral" } + ] + }, + { + "chart_id": "runtime_activation_boundary", + "display_name": "runtime 啟用邊界", + "chart_type": "funnel", + "unit": "actions", + "series": [ + { "label": "可見報告", "value": 3, "tone": "ok" }, + { "label": "Telegram 草案", "value": 3, "tone": "warn" }, + { "label": "live 發送", "value": 0, "tone": "danger" }, + { "label": "自動優化", "value": 0, "tone": "danger" } + ] + } + ], + "operator_answer_cards": [ + { + "answer_id": "daily_weekly_monthly_complete", + "question": "日報、週報、月報完成了嗎?", + "answer": "完成可視化與契約層:三種報告都是 100%,治理頁可見;live 定時發送尚未啟用。", + "status": "complete" + }, + { + "answer_id": "per_agent_status_visible", + "question": "每個 AI Agent 的工作狀態報告看得到嗎?", + "answer": "看得到:OpenClaw、Hermes、NemoTron 都有角色、工作量、完成數、待審核數、Telegram 政策與學習狀態。", + "status": "complete" + }, + { + "answer_id": "telegram_and_auto_optimization_boundary", + "question": "Telegram 告警與自動優化現在有沒有 live 執行?", + "answer": "目前沒有。P2-108 只展示草案與邊界;live Telegram、讀報後 AI 分析、中低風險自動優化仍需下一道 runtime gate。", + "status": "guarded" + }, + { + "answer_id": "high_risk_review_policy", + "question": "高風險工作誰審核?", + "answer": "高風險一律保留人工審核;AI Agent 只能提出方案、風險、回滾與驗證計畫。", + "status": "guarded" + } + ], + "activation_boundaries": { + "scheduler_enabled": false, + "gateway_queue_write_enabled": false, + "telegram_send_enabled": false, + "report_receipt_write_enabled": false, + "ai_analysis_run_enabled": false, + "medium_low_auto_execution_enabled": false, + "production_optimization_write_enabled": false, + "high_risk_requires_human_approval": true + }, + "display_redaction_contract": { + "redaction_required": true, + "raw_prompt_display_allowed": false, + "private_reasoning_display_allowed": false, + "secret_value_display_allowed": false, + "internal_transcript_display_allowed": false + }, + "rollups": { + "report_card_count": 3, + "agent_status_count": 3, + "visible_chart_count": 3, + "operator_answer_count": 4, + "completed_report_count": 3, + "workload_unit_total": 91, + "workload_done_total": 79, + "workload_waiting_approval_total": 12, + "live_delivery_count": 0, + "live_telegram_send_count": 0, + "live_runtime_work_units": 0, + "live_auto_optimization_count": 0, + "high_risk_requires_human_approval": true + } +} diff --git a/docs/schemas/ai_agent_report_status_board_v1.schema.json b/docs/schemas/ai_agent_report_status_board_v1.schema.json new file mode 100644 index 000000000..e83843e4c --- /dev/null +++ b/docs/schemas/ai_agent_report_status_board_v1.schema.json @@ -0,0 +1,245 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://awoooi.wooo.work/schemas/ai_agent_report_status_board_v1.schema.json", + "title": "AI Agent Report Status Board v1", + "type": "object", + "required": [ + "schema_version", + "generated_at", + "program_status", + "source_refs", + "report_completion_truth", + "report_status_cards", + "agent_status_reports", + "visible_charts", + "operator_answer_cards", + "activation_boundaries", + "display_redaction_contract", + "rollups" + ], + "properties": { + "schema_version": { "const": "ai_agent_report_status_board_v1" }, + "generated_at": { "type": "string" }, + "program_status": { + "type": "object", + "required": [ + "overall_completion_percent", + "current_priority", + "current_task_id", + "next_task_id", + "read_only_mode", + "runtime_authority", + "status_note" + ], + "properties": { + "overall_completion_percent": { "const": 100 }, + "current_priority": { "enum": ["P0", "P1", "P2", "P3"] }, + "current_task_id": { "const": "P2-108" }, + "next_task_id": { "type": "string" }, + "read_only_mode": { "const": true }, + "runtime_authority": { "const": "report_status_board_only_no_live_send_or_write" }, + "status_note": { "type": "string" } + }, + "additionalProperties": false + }, + "source_refs": { "type": "array", "items": { "type": "string" }, "minItems": 1 }, + "report_completion_truth": { + "type": "object", + "required": [ + "daily_report_visible", + "weekly_report_visible", + "monthly_report_visible", + "per_agent_status_visible", + "workload_metrics_visible", + "chart_package_visible", + "telegram_digest_draft_visible", + "live_report_delivery_enabled", + "live_telegram_send_count_24h", + "ai_post_report_analysis_enabled", + "medium_low_auto_optimization_enabled", + "high_risk_human_approval_required", + "live_auto_optimization_count_24h", + "truth_note" + ], + "properties": { + "daily_report_visible": { "const": true }, + "weekly_report_visible": { "const": true }, + "monthly_report_visible": { "const": true }, + "per_agent_status_visible": { "const": true }, + "workload_metrics_visible": { "const": true }, + "chart_package_visible": { "const": true }, + "telegram_digest_draft_visible": { "const": true }, + "live_report_delivery_enabled": { "const": false }, + "live_telegram_send_count_24h": { "const": 0 }, + "ai_post_report_analysis_enabled": { "const": false }, + "medium_low_auto_optimization_enabled": { "const": false }, + "high_risk_human_approval_required": { "const": true }, + "live_auto_optimization_count_24h": { "const": 0 }, + "truth_note": { "type": "string" } + }, + "additionalProperties": false + }, + "report_status_cards": { + "type": "array", + "minItems": 3, + "items": { + "type": "object", + "required": [ + "cadence_id", + "display_name", + "owner_agent", + "completion_percent", + "contract_state", + "delivery_state", + "sections_count", + "chart_count", + "work_units_total", + "live_delivery_count", + "next_gate" + ], + "properties": { + "cadence_id": { "enum": ["daily", "weekly", "monthly"] }, + "display_name": { "type": "string" }, + "owner_agent": { "enum": ["openclaw", "hermes", "nemotron"] }, + "completion_percent": { "const": 100 }, + "contract_state": { "const": "visible_contract_ready" }, + "delivery_state": { "const": "draft_only" }, + "sections_count": { "type": "integer", "minimum": 1 }, + "chart_count": { "type": "integer", "minimum": 1 }, + "work_units_total": { "type": "integer", "minimum": 0 }, + "live_delivery_count": { "const": 0 }, + "next_gate": { "type": "string" } + }, + "additionalProperties": false + } + }, + "agent_status_reports": { + "type": "array", + "minItems": 3, + "items": { + "type": "object", + "required": [ + "agent_id", + "display_name", + "primary_role", + "current_state", + "work_units_total", + "work_units_done", + "work_units_waiting_approval", + "report_sections_owned", + "analysis_recommendations_owned", + "live_runtime_work_units_24h", + "communication_state", + "learning_state", + "telegram_policy", + "status_note" + ], + "properties": { + "agent_id": { "enum": ["openclaw", "hermes", "nemotron"] }, + "display_name": { "type": "string" }, + "primary_role": { "type": "string" }, + "current_state": { "type": "string" }, + "work_units_total": { "type": "integer", "minimum": 0 }, + "work_units_done": { "type": "integer", "minimum": 0 }, + "work_units_waiting_approval": { "type": "integer", "minimum": 0 }, + "report_sections_owned": { "type": "integer", "minimum": 0 }, + "analysis_recommendations_owned": { "type": "integer", "minimum": 0 }, + "live_runtime_work_units_24h": { "const": 0 }, + "communication_state": { "type": "string" }, + "learning_state": { "type": "string" }, + "telegram_policy": { "type": "string" }, + "status_note": { "type": "string" } + }, + "additionalProperties": false + } + }, + "visible_charts": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["chart_id", "display_name", "chart_type", "unit", "series"], + "properties": { + "chart_id": { "type": "string" }, + "display_name": { "type": "string" }, + "chart_type": { "type": "string" }, + "unit": { "type": "string" }, + "series": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["label", "value", "tone"], + "properties": { + "label": { "type": "string" }, + "value": { "type": "integer", "minimum": 0 }, + "tone": { "enum": ["ok", "warn", "danger", "neutral"] } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + }, + "operator_answer_cards": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["answer_id", "question", "answer", "status"], + "properties": { + "answer_id": { "type": "string" }, + "question": { "type": "string" }, + "answer": { "type": "string" }, + "status": { "enum": ["complete", "guarded", "next_gate"] } + }, + "additionalProperties": false + } + }, + "activation_boundaries": { + "type": "object", + "required": [ + "scheduler_enabled", + "gateway_queue_write_enabled", + "telegram_send_enabled", + "report_receipt_write_enabled", + "ai_analysis_run_enabled", + "medium_low_auto_execution_enabled", + "production_optimization_write_enabled", + "high_risk_requires_human_approval" + ], + "properties": { + "scheduler_enabled": { "const": false }, + "gateway_queue_write_enabled": { "const": false }, + "telegram_send_enabled": { "const": false }, + "report_receipt_write_enabled": { "const": false }, + "ai_analysis_run_enabled": { "const": false }, + "medium_low_auto_execution_enabled": { "const": false }, + "production_optimization_write_enabled": { "const": false }, + "high_risk_requires_human_approval": { "const": true } + }, + "additionalProperties": false + }, + "display_redaction_contract": { + "type": "object", + "required": [ + "redaction_required", + "raw_prompt_display_allowed", + "private_reasoning_display_allowed", + "secret_value_display_allowed", + "internal_transcript_display_allowed" + ], + "properties": { + "redaction_required": { "const": true }, + "raw_prompt_display_allowed": { "const": false }, + "private_reasoning_display_allowed": { "const": false }, + "secret_value_display_allowed": { "const": false }, + "internal_transcript_display_allowed": { "const": false } + }, + "additionalProperties": false + }, + "rollups": { "type": "object" } + }, + "additionalProperties": false +} diff --git a/docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md b/docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md index b70b86e1a..191ef66f1 100644 --- a/docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md +++ b/docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md @@ -645,6 +645,7 @@ Alert / Sentry / SigNoz / Gitea / Market Watch / Operator | `docs/evaluations/ai_agent_critic_reviewer_result_capture_2026-06-13.json` + `GET /api/v1/agents/agent-critic-reviewer-result-capture` | P2-105 critic / reviewer 評分與 result capture 契約;承接 P2-104 approved gap `63` 與 failed candidate `1`,建立 5 張 scorecard、5 個 result capture contract、6 個 promotion gate、4 條 candidate route;runtime Critic score、Reviewer score、result capture write、learning write、PlayBook trust write、Gateway queue、Telegram、production write、secret read 與 destructive action 全部 `0 / false`,下一步 P2-106 owner-approved result capture dry-run | | `docs/evaluations/ai_agent_owner_approved_result_capture_dry_run_2026-06-13.json` + `GET /api/v1/agents/agent-owner-approved-result-capture-dry-run` | P2-106 owner-approved result capture dry-run;承接 P2-105 scorecard / result capture contract / promotion gate,建立 5 個 result capture dry-run template、5 個 critic / reviewer score fixture、7 個 dry-run gate 與 5 個 operator action;owner approval received、dry-run preview generated、score write、result capture write、learning write、PlayBook trust write、Gateway queue、Telegram、production write、secret read 與 destructive action 全部 `0 / false`,已由 P2-107 承接 | | `docs/evaluations/ai_agent_owner_approved_result_capture_readback_2026-06-13.json` + `GET /api/v1/agents/agent-owner-approved-result-capture-readback` | P2-107 owner-approved result capture readback / promotion readiness;承接 P2-106 no-write dry-run,建立 5 個 readback digest、5 個 promotion readiness review、4 條 failure lane、4 個 reviewer queue preview 與 5 個 operator action;canonical runtime readback、owner approval received、readback digest generated、promotion approved、reviewer queue write、score write、result capture write、learning write、PlayBook trust write、Gateway queue、Telegram、production write、secret read 與 destructive action 全部 `0 / false`,下一步 P2-108 | +| `docs/evaluations/ai_agent_report_status_board_2026-06-13.json` + `GET /api/v1/agents/agent-report-status-board` | P2-108 日週月報與 Agent 工作狀態總覽;承接 P2-403J / P2-403L-M-N / P2-107,將日報、週報、月報、OpenClaw / Hermes / NemoTron 工作狀態、工作量、圖表與 operator answer cards 收斂到治理頁;三種報告可見完成度 `100%`,Agent 狀態 `3`、圖表 `3`、工作量 `91`、已完成 `79`、待審核 `12`;scheduler、Gateway queue write、Telegram send、讀報回執、AI analysis run、中低風險 auto execution、production optimization write 全部 `0 / false`,下一步 P2-109 | | `docs/evaluations/ai_agent_live_read_model_gate_2026-06-11.json` + `GET /api/v1/agents/agent-live-read-model-gate` | P2-403B AgentSession / Redis Streams live read model gate;定義 safe fields、Redis envelope、worker gate、rollback plan 與 no-write smoke,不連 DB、不讀寫 Redis、不啟動 worker | #### 3.2.1c 2026-06-11 AI Agent 主動營運委派與版本生命週期契約 @@ -741,6 +742,7 @@ Repo / registry / release notes / K8s / host / observability / backup evidence 26. 批准前加入 critic / reviewer 評分與 result capture。✅ P2-105 已完成;scorecard `5`、result capture contract `5`、promotion gate `6`、candidate route `4`,approved gap `63`、failed candidate `1`;runtime score、result capture write、learning write、PlayBook trust write、Gateway queue write、Telegram send 與 production write 仍為 `0 / false`。已由 P2-106 承接。 27. 建立 owner-approved result capture dry-run。✅ P2-106 已完成;result capture dry-run template `5`、score fixture `5`、dry-run gate `7`、operator action `5`,owner approval received、dry-run preview generated、score write、result capture write、learning write、PlayBook trust write、Gateway queue write、Telegram send 與 production write 仍為 `0 / false`。已由 P2-107 承接。 28. 建立 owner-approved result capture readback / promotion readiness。✅ P2-107 已完成;readback digest `5`、promotion review `5`、failure lane `4`、reviewer queue preview `4`、operator action `5`,canonical runtime readback、owner approval received、readback digest generated、promotion approved、reviewer queue write、score / result capture / learning / trust / Gateway / Telegram / production write 仍為 `0 / false`。下一步 P2-108。 +29. 建立日週月報與 Agent 工作狀態總覽。✅ P2-108 已完成;日報 / 週報 / 月報可見完成度皆 `100%`,OpenClaw / Hermes / NemoTron 工作狀態報告 `3`,圖表 `3`,operator answer card `4`,工作量 `91`、已完成 `79`、待審核 `12`;scheduler、Gateway queue write、Telegram send、report receipt、AI analysis run、中低風險 auto worker、production optimization write 仍為 `0 / false`。下一步 P2-109。 #### 3.2.1d 2026-06-11 Agent 互動、學習與成長證據面 @@ -779,6 +781,8 @@ Repo / registry / release notes / K8s / host / observability / backup evidence | `docs/evaluations/ai_agent_owner_approved_result_capture_dry_run_2026-06-13.json` + `GET /api/v1/agents/agent-owner-approved-result-capture-dry-run` | P2-106 committed snapshot;5 個 no-write result capture template、5 個 critic / reviewer score fixture、7 個 dry-run gate、5 個 operator action;不寫 score、不寫 result capture、不寫 learning、不更新 PlayBook trust、不送 Telegram、不讀 secret、不執行 destructive action | | `docs/schemas/ai_agent_owner_approved_result_capture_readback_v1.schema.json` | P2-107 owner-approved result capture readback schema;強制 canonical runtime readback、owner approval received、readback digest generated、promotion approved、reviewer queue write、score write、result capture write、learning write、PlayBook trust write、Gateway queue、Telegram、production write、secret read 與 destructive action 全部維持 `0 / false` | | `docs/evaluations/ai_agent_owner_approved_result_capture_readback_2026-06-13.json` + `GET /api/v1/agents/agent-owner-approved-result-capture-readback` | P2-107 committed snapshot;5 個 fixture-only readback digest、5 個 promotion readiness review、4 條 failure lane、4 個 reviewer queue preview、5 個 operator action;不讀 canonical runtime target、不寫 reviewer queue、不寫 score、不寫 result capture、不寫 learning、不更新 PlayBook trust、不送 Telegram、不讀 secret、不執行 destructive action | +| `docs/schemas/ai_agent_report_status_board_v1.schema.json` | P2-108 日週月報與 Agent 工作狀態總覽 schema;強制日報 / 週報 / 月報、每個 Agent 狀態、工作量與圖表可見,同時保持 scheduler、Gateway queue write、Telegram send、report receipt、AI analysis run、中低風險 auto execution、production optimization write 全部未啟用 | +| `docs/evaluations/ai_agent_report_status_board_2026-06-13.json` + `GET /api/v1/agents/agent-report-status-board` | P2-108 committed snapshot;三種報告 `100%` 可見、3 個 Agent 狀態報告、3 張圖表、4 張統帥問答卡;工作量 `91`、已完成 `79`、待審核 `12`,live delivery / Telegram send / runtime work / auto optimization 全部 `0` | | `apps/api/src/services/ai_agent_interaction_learning_proof.py` | 只讀 loader;強制 live flags / DB / Redis / Telegram / transcript / 私有推理全部關閉 | | `GET /api/v1/agents/agent-interaction-learning-proof` | 治理 API;只回傳證據面,不啟動 worker、不碰 live DB/Redis、不發 Telegram | | `docs/schemas/ai_agent_live_read_model_gate_v1.schema.json` | P2-403B live read model gate schema;強制 DB / Redis / worker / Telegram / learning writeback 仍需批准 |