From ab242018b193cf252b1593fe73ca8a66dcbadc4e Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 13 Jun 2026 16:15:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(governance):=20=E6=96=B0=E5=A2=9E=20report?= =?UTF-8?q?=20live=20delivery=20=E6=89=B9=E5=87=86=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api/src/api/v1/agents.py | 33 + ...t_report_live_delivery_approval_package.py | 418 ++++++++++ ...t_report_live_delivery_approval_package.py | 139 ++++ ...port_live_delivery_approval_package_api.py | 50 ++ apps/web/messages/en.json | 89 ++ apps/web/messages/zh-TW.json | 89 ++ .../tabs/automation-inventory-tab.tsx | 256 +++++- apps/web/src/lib/api-client.ts | 168 ++++ docs/LOGBOOK.md | 23 + ...AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md | 6 +- ...T_INTERACTION_LEARNING_PROOF_2026-06-11.md | 17 +- ..._delivery_approval_package_2026-06-13.json | 466 +++++++++++ ...e_delivery_approval_package_v1.schema.json | 787 ++++++++++++++++++ ...-04-15-MASTER-ai-autonomous-flywheel-v2.md | 12 + 14 files changed, 2543 insertions(+), 10 deletions(-) create mode 100644 apps/api/src/services/ai_agent_report_live_delivery_approval_package.py create mode 100644 apps/api/tests/test_ai_agent_report_live_delivery_approval_package.py create mode 100644 apps/api/tests/test_ai_agent_report_live_delivery_approval_package_api.py create mode 100644 docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json create mode 100644 docs/schemas/ai_agent_report_live_delivery_approval_package_v1.schema.json diff --git a/apps/api/src/api/v1/agents.py b/apps/api/src/api/v1/agents.py index 752b6e2f..f1094c2d 100644 --- a/apps/api/src/api/v1/agents.py +++ b/apps/api/src/api/v1/agents.py @@ -109,6 +109,9 @@ from src.services.ai_agent_runtime_readback_approval_package import ( from src.services.ai_agent_runtime_readback_implementation_review import ( load_latest_ai_agent_runtime_readback_implementation_review, ) +from src.services.ai_agent_report_live_delivery_approval_package import ( + load_latest_ai_agent_report_live_delivery_approval_package, +) from src.services.ai_agent_report_automation_review import ( load_latest_ai_agent_report_automation_review, ) @@ -1359,6 +1362,36 @@ async def get_agent_runtime_readback_implementation_review() -> dict[str, Any]: ) from exc +@router.get( + "/agent-report-live-delivery-approval-package", + response_model=dict[str, Any], + summary="取得 AI Agent report live delivery 批准包", + description=( + "讀取最新已提交的 P2-111 report live delivery approval package;" + "此端點只回傳日報、週報、月報、失敗限定摘要與讀報回執的實發批准包、" + "route lock、payload redaction、no-send receipt 與 operator action," + "不排程、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、" + "不啟動 AI analysis、不做中低風險自動優化、不寫 production target、不讀 secret。" + ), +) +async def get_agent_report_live_delivery_approval_package() -> dict[str, Any]: + """Return the latest read-only report live delivery approval package.""" + try: + payload = await asyncio.to_thread(load_latest_ai_agent_report_live_delivery_approval_package) + 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_live_delivery_approval_package_invalid", error=str(exc)) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="AI Agent report live delivery approval package 無效", + ) from exc + + @router.get( "/agent-owner-approved-fixture-dry-run", response_model=dict[str, Any], diff --git a/apps/api/src/services/ai_agent_report_live_delivery_approval_package.py b/apps/api/src/services/ai_agent_report_live_delivery_approval_package.py new file mode 100644 index 00000000..8c4d9abb --- /dev/null +++ b/apps/api/src/services/ai_agent_report_live_delivery_approval_package.py @@ -0,0 +1,418 @@ +""" +AI Agent report live delivery approval package snapshot. + +Loads the latest committed P2-111 report delivery approval package. This module +validates committed evidence only; it never schedules report delivery, writes +Gateway queues, sends Telegram messages, calls Bot API, writes read receipts, +starts AI analysis workers, writes production optimization results, reads +secrets, or runs destructive operations. +""" + +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_live_delivery_approval_package_*.json" +_SCHEMA_VERSION = "ai_agent_report_live_delivery_approval_package_v1" +_RUNTIME_AUTHORITY = "report_live_delivery_approval_package_only_no_live_send_or_write" + + +def load_latest_ai_agent_report_live_delivery_approval_package( + evaluations_dir: Path | None = None, +) -> dict[str, Any]: + """Load the newest committed report live delivery approval package.""" + directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR + candidates = sorted(directory.glob(_SNAPSHOT_PATTERN)) + if not candidates: + raise FileNotFoundError(f"no AI Agent report live delivery approval package 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_prior_report_status_board(payload, str(latest)) + _require_prior_runtime_review(payload, str(latest)) + _require_delivery_truth(payload, str(latest)) + _require_delivery_packets(payload, str(latest)) + _require_route_lock_gates(payload, str(latest)) + _require_payload_redaction_checks(payload, str(latest)) + _require_dry_run_receipts(payload, str(latest)) + _require_operator_actions(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-111": + raise ValueError(f"{label}: current_task_id must be P2-111") + if status.get("next_task_id") != "P2-112": + raise ValueError(f"{label}: next_task_id must be P2-112") + if status.get("overall_completion_percent") != 100: + raise ValueError(f"{label}: P2-111 approval package must be 100 percent complete") + + +def _require_prior_report_status_board(payload: dict[str, Any], label: str) -> None: + prior = payload.get("prior_report_status_board") or {} + expected = { + "source_schema_version": "ai_agent_report_status_board_v1", + "report_card_count": 3, + "agent_status_report_count": 3, + "visible_chart_count": 3, + "operator_answer_count": 4, + "work_units_total": 91, + "work_units_done": 79, + "work_units_waiting_approval": 12, + "live_delivery_count": 0, + "live_telegram_send_count_24h": 0, + "live_auto_optimization_count_24h": 0, + } + mismatches = _mismatches(prior, expected) + if mismatches: + raise ValueError(f"{label}: P2-108 prior report status counts mismatch: {mismatches}") + if not prior.get("readiness_note"): + raise ValueError(f"{label}: prior_report_status_board.readiness_note is required") + + +def _require_prior_runtime_review(payload: dict[str, Any], label: str) -> None: + prior = payload.get("prior_runtime_review") or {} + expected = { + "approval_package_schema_version": "ai_agent_runtime_readback_approval_package_v1", + "implementation_review_schema_version": "ai_agent_runtime_readback_implementation_review_v1", + "telegram_failure_receipt_gate_count": 4, + "implementation_blocker_count": 5, + "no_write_verifier_check_count": 5, + "owner_approval_received_count": 0, + "runtime_readback_execution_count": 0, + "live_query_count": 0, + "telegram_failure_receipt_send_count": 0, + "bot_api_call_count": 0, + "gateway_queue_write_count": 0, + "production_write_count": 0, + } + mismatches = _mismatches(prior, expected) + if mismatches: + raise ValueError(f"{label}: P2-109/P2-110 prior runtime counts mismatch: {mismatches}") + if not prior.get("readiness_note"): + raise ValueError(f"{label}: prior_runtime_review.readiness_note is required") + + +def _require_delivery_truth(payload: dict[str, Any], label: str) -> None: + truth = payload.get("delivery_approval_truth") or {} + required_true = { + "p2_108_report_status_loaded", + "p2_109_failure_receipt_gate_loaded", + "p2_110_implementation_review_loaded", + "delivery_approval_package_ready", + "daily_delivery_package_ready", + "weekly_delivery_package_ready", + "monthly_delivery_package_ready", + "sre_war_room_route_locked", + "payload_redaction_ready", + "dry_run_receipt_ready", + "owner_review_required_before_delivery", + } + missing = sorted(field for field in required_true if truth.get(field) is not True) + if missing: + raise ValueError(f"{label}: delivery approval ready flags must remain true: {missing}") + + required_false = { + "scheduler_enabled", + "gateway_queue_write_enabled", + "telegram_send_enabled", + "bot_api_call_enabled", + "report_receipt_write_enabled", + "ai_analysis_run_enabled", + "medium_low_auto_optimization_enabled", + "production_write_enabled", + "secret_read_enabled", + "destructive_operation_enabled", + } + unsafe = sorted(field for field in required_false if truth.get(field) is not False) + if unsafe: + raise ValueError(f"{label}: live send/write flags must remain false: {unsafe}") + + zero_counts = { + "owner_approval_received_count", + "scheduled_delivery_count_24h", + "gateway_queue_write_count_24h", + "telegram_send_count_24h", + "bot_api_call_count_24h", + "report_receipt_write_count_24h", + "ai_analysis_run_count_24h", + "auto_optimization_count_24h", + "production_write_count_24h", + "secret_read_count_24h", + "destructive_operation_count_24h", + } + non_zero = sorted(field for field in zero_counts if truth.get(field) != 0) + if non_zero: + raise ValueError(f"{label}: report delivery live counters must remain zero: {non_zero}") + if not truth.get("truth_note"): + raise ValueError(f"{label}: delivery_approval_truth.truth_note is required") + + +def _require_delivery_packets(payload: dict[str, Any], label: str) -> None: + packets = payload.get("delivery_approval_packets") or [] + packet_ids = {packet.get("packet_id") for packet in packets} + required = { + "daily_report_delivery_approval", + "weekly_report_delivery_approval", + "monthly_report_delivery_approval", + "failure_only_digest_approval", + "report_receipt_readback_approval", + } + if packet_ids != required: + raise ValueError(f"{label}: delivery approval packets must match {sorted(required)}") + + valid_statuses = {"approval_required", "ready_for_owner_review", "blocked_by_policy"} + valid_risks = {"medium", "high", "critical"} + for packet in packets: + packet_id = packet.get("packet_id") + if packet.get("status") not in valid_statuses: + raise ValueError(f"{label}: packet {packet_id} status is invalid") + if packet.get("risk_tier") not in valid_risks: + raise ValueError(f"{label}: packet {packet_id} risk_tier is invalid") + if packet.get("approval_required") is not True: + raise ValueError(f"{label}: packet {packet_id} approval_required must remain true") + if packet.get("no_send_mode") is not True: + raise ValueError(f"{label}: packet {packet_id} no_send_mode must remain true") + if not packet.get("required_approval_fields") or not packet.get("blocked_runtime_actions"): + raise ValueError(f"{label}: packet {packet_id} must list approval fields and blocked actions") + if not packet.get("operator_guidance"): + raise ValueError(f"{label}: packet {packet_id} must include operator guidance") + if not _is_redacted_sha256(packet.get("evidence_hash")): + raise ValueError(f"{label}: packet {packet_id} must expose evidence_hash") + + +def _require_route_lock_gates(payload: dict[str, Any], label: str) -> None: + gates = payload.get("route_lock_gates") or [] + gate_ids = {gate.get("gate_id") for gate in gates} + required = { + "sre_war_room_route_lock", + "legacy_bot_suppression", + "dedupe_fingerprint_lock", + "delivery_window_gate", + } + if gate_ids != required: + raise ValueError(f"{label}: route lock gates must match {sorted(required)}") + for gate in gates: + gate_id = gate.get("gate_id") + if gate.get("status") not in {"ready_for_owner_review", "approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: route gate {gate_id} status is invalid") + if not gate.get("required_evidence") or not gate.get("blocked_routes"): + raise ValueError(f"{label}: route gate {gate_id} must list evidence and blocked routes") + for field in ("telegram_send_enabled", "bot_api_call_enabled", "gateway_queue_write_enabled"): + if gate.get(field) is not False: + raise ValueError(f"{label}: route gate {gate_id} {field} must remain false") + if not _is_redacted_sha256(gate.get("evidence_hash")): + raise ValueError(f"{label}: route gate {gate_id} must expose evidence_hash") + + +def _require_payload_redaction_checks(payload: dict[str, Any], label: str) -> None: + checks = payload.get("payload_redaction_checks") or [] + check_ids = {check.get("check_id") for check in checks} + required = { + "no_raw_prompt", + "no_private_reasoning", + "no_secret_values", + "no_raw_telegram_payload", + "no_internal_collaboration_content", + } + if check_ids != required: + raise ValueError(f"{label}: payload redaction checks must match {sorted(required)}") + for check in checks: + check_id = check.get("check_id") + if check.get("status") not in {"ready", "blocked_by_policy"}: + raise ValueError(f"{label}: redaction check {check_id} status is invalid") + if check.get("display_allowed") is not False: + raise ValueError(f"{label}: redaction check {check_id} display_allowed must remain false") + if not check.get("required_rule") or not check.get("failure_if_missing"): + raise ValueError(f"{label}: redaction check {check_id} must include rule and failure explanation") + if not _is_redacted_sha256(check.get("evidence_hash")): + raise ValueError(f"{label}: redaction check {check_id} must expose evidence_hash") + + +def _require_dry_run_receipts(payload: dict[str, Any], label: str) -> None: + receipts = payload.get("dry_run_delivery_receipts") or [] + receipt_ids = {receipt.get("receipt_id") for receipt in receipts} + required = { + "daily_digest_no_send_receipt", + "weekly_digest_no_send_receipt", + "monthly_digest_no_send_receipt", + "failure_only_no_send_receipt", + } + if receipt_ids != required: + raise ValueError(f"{label}: dry-run receipts must match {sorted(required)}") + for receipt in receipts: + receipt_id = receipt.get("receipt_id") + if receipt.get("status") not in {"ready_for_owner_review", "blocked_by_policy"}: + raise ValueError(f"{label}: dry-run receipt {receipt_id} status is invalid") + if receipt.get("live_send_count") != 0: + raise ValueError(f"{label}: dry-run receipt {receipt_id} live_send_count must remain zero") + if receipt.get("receipt_write_allowed") is not False: + raise ValueError(f"{label}: dry-run receipt {receipt_id} receipt_write_allowed must remain false") + if not receipt.get("required_fields"): + raise ValueError(f"{label}: dry-run receipt {receipt_id} must list required fields") + if not _is_redacted_sha256(receipt.get("evidence_hash")): + raise ValueError(f"{label}: dry-run receipt {receipt_id} must expose evidence_hash") + + +def _require_operator_actions(payload: dict[str, Any], label: str) -> None: + actions = payload.get("operator_actions") or [] + action_types = {action.get("action_type") for action in actions} + required = { + "review_delivery_packet", + "validate_sre_route", + "validate_payload_redaction", + "validate_zero_send_counters", + "reject_or_promote", + } + if action_types != required: + raise ValueError(f"{label}: operator actions must match {sorted(required)}") + for action in actions: + if action.get("live_send_allowed") is not False: + raise ValueError(f"{label}: operator action {action.get('action_id')} must not allow live send") + if not action.get("operator_instruction"): + raise ValueError(f"{label}: operator action {action.get('action_id')} must include instruction") + + +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 must remain required") + required_false = { + "raw_prompt_display_allowed", + "private_reasoning_display_allowed", + "secret_value_display_allowed", + "raw_telegram_payload_display_allowed", + "internal_collaboration_content_display_allowed", + } + unsafe = sorted(field for field in required_false if contract.get(field) is not False) + if unsafe: + raise ValueError(f"{label}: display redaction fields must remain false: {unsafe}") + if not contract.get("frontend_display_policy"): + raise ValueError(f"{label}: frontend_display_policy is required") + + +def _require_no_forbidden_display_terms(payload: dict[str, Any], label: str) -> None: + forbidden_terms = { + "工作視窗", + "對話內容", + "批准!繼續", + "In app browser", + "My request for Codex", + "browser_context", + "codex_user_message", + "prompt_text", + "raw prompt", + "private reasoning", + "chain of thought", + "private_reasoning", + "chain_of_thought", + "authorization_header", + "authorization header", + "secret value", + "raw payload", + "raw Telegram payload", + "work window transcript", + "internal collaboration transcript", + } + technical_identifier_fields = { + "action_id", + "action_type", + "check_id", + "gate_id", + "packet_id", + "receipt_id", + "required_rule", + } + hits: list[str] = [] + + def walk(value: Any, path: str) -> None: + if isinstance(value, dict): + for key, nested in value.items(): + walk(nested, f"{path}.{key}" if path else str(key)) + return + if isinstance(value, list): + for index, nested in enumerate(value): + walk(nested, f"{path}[{index}]") + return + if isinstance(value, str): + field_name = path.rsplit(".", 1)[-1] + if field_name in technical_identifier_fields: + return + matched = sorted(term for term in forbidden_terms if term in value) + if matched: + hits.append(f"{path}: {', '.join(matched)}") + + walk(payload, "") + if hits: + raise ValueError(f"{label}: forbidden display terms found: {hits}") + + +def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None: + rollups = payload.get("rollups") or {} + truth = payload.get("delivery_approval_truth") or {} + packets = payload.get("delivery_approval_packets") or [] + gates = payload.get("route_lock_gates") or [] + checks = payload.get("payload_redaction_checks") or [] + receipts = payload.get("dry_run_delivery_receipts") or [] + actions = payload.get("operator_actions") or [] + expected = { + "delivery_approval_packet_count": len(packets), + "route_lock_gate_count": len(gates), + "payload_redaction_check_count": len(checks), + "dry_run_delivery_receipt_count": len(receipts), + "operator_action_count": len(actions), + "approval_required_packet_count": sum(1 for packet in packets if packet.get("status") == "approval_required"), + "blocked_packet_count": sum(1 for packet in packets if packet.get("status") == "blocked_by_policy"), + "blocked_route_gate_count": sum(1 for gate in gates if gate.get("status") == "blocked_by_policy"), + "blocked_receipt_count": sum(1 for receipt in receipts if receipt.get("status") == "blocked_by_policy"), + "owner_approval_received_count": truth.get("owner_approval_received_count"), + "scheduled_delivery_count": truth.get("scheduled_delivery_count_24h"), + "gateway_queue_write_count": truth.get("gateway_queue_write_count_24h"), + "telegram_send_count": truth.get("telegram_send_count_24h"), + "bot_api_call_count": truth.get("bot_api_call_count_24h"), + "report_receipt_write_count": truth.get("report_receipt_write_count_24h"), + "ai_analysis_run_count": truth.get("ai_analysis_run_count_24h"), + "auto_optimization_count": truth.get("auto_optimization_count_24h"), + "production_write_count": truth.get("production_write_count_24h"), + "secret_read_count": truth.get("secret_read_count_24h"), + "destructive_operation_count": truth.get("destructive_operation_count_24h"), + } + mismatches = _mismatches(rollups, expected) + if mismatches: + raise ValueError(f"{label}: rollup counts mismatch: {mismatches}") + + +def _mismatches(payload: dict[str, Any], expected: dict[str, Any]) -> dict[str, dict[str, Any]]: + return { + key: {"expected": expected_value, "actual": payload.get(key)} + for key, expected_value in expected.items() + if payload.get(key) != expected_value + } + + +def _is_redacted_sha256(value: Any) -> bool: + if not isinstance(value, str): + return False + if not value.startswith("sha256:") or len(value) != 71: + return False + return all(char in "0123456789abcdef" for char in value.removeprefix("sha256:")) diff --git a/apps/api/tests/test_ai_agent_report_live_delivery_approval_package.py b/apps/api/tests/test_ai_agent_report_live_delivery_approval_package.py new file mode 100644 index 00000000..b38555a9 --- /dev/null +++ b/apps/api/tests/test_ai_agent_report_live_delivery_approval_package.py @@ -0,0 +1,139 @@ +import copy +import json + +import pytest + +from src.services.ai_agent_report_live_delivery_approval_package import ( + load_latest_ai_agent_report_live_delivery_approval_package, +) + + +def _write_snapshot(tmp_path, payload): + path = tmp_path / "ai_agent_report_live_delivery_approval_package_2026-06-13.json" + path.write_text(json.dumps(payload), encoding="utf-8") + return path + + +def test_load_latest_ai_agent_report_live_delivery_approval_package(): + data = load_latest_ai_agent_report_live_delivery_approval_package() + + assert data["schema_version"] == "ai_agent_report_live_delivery_approval_package_v1" + assert data["program_status"]["current_task_id"] == "P2-111" + assert data["program_status"]["next_task_id"] == "P2-112" + assert data["program_status"]["overall_completion_percent"] == 100 + assert data["prior_report_status_board"]["source_schema_version"] == "ai_agent_report_status_board_v1" + assert data["prior_report_status_board"]["report_card_count"] == 3 + assert data["prior_report_status_board"]["work_units_total"] == 91 + assert data["prior_runtime_review"]["approval_package_schema_version"] == "ai_agent_runtime_readback_approval_package_v1" + assert data["prior_runtime_review"]["implementation_review_schema_version"] == "ai_agent_runtime_readback_implementation_review_v1" + assert data["delivery_approval_truth"]["p2_108_report_status_loaded"] is True + assert data["delivery_approval_truth"]["p2_109_failure_receipt_gate_loaded"] is True + assert data["delivery_approval_truth"]["p2_110_implementation_review_loaded"] is True + assert data["delivery_approval_truth"]["delivery_approval_package_ready"] is True + assert data["delivery_approval_truth"]["sre_war_room_route_locked"] is True + assert data["delivery_approval_truth"]["scheduler_enabled"] is False + assert data["delivery_approval_truth"]["gateway_queue_write_enabled"] is False + assert data["delivery_approval_truth"]["telegram_send_enabled"] is False + assert data["delivery_approval_truth"]["bot_api_call_enabled"] is False + assert data["delivery_approval_truth"]["report_receipt_write_enabled"] is False + assert data["delivery_approval_truth"]["ai_analysis_run_enabled"] is False + assert data["delivery_approval_truth"]["scheduled_delivery_count_24h"] == 0 + assert data["delivery_approval_truth"]["telegram_send_count_24h"] == 0 + assert data["rollups"]["delivery_approval_packet_count"] == 5 + assert data["rollups"]["route_lock_gate_count"] == 4 + assert data["rollups"]["payload_redaction_check_count"] == 5 + assert data["rollups"]["dry_run_delivery_receipt_count"] == 4 + assert data["rollups"]["operator_action_count"] == 5 + assert data["rollups"]["approval_required_packet_count"] == 3 + assert data["rollups"]["blocked_packet_count"] == 1 + assert data["rollups"]["blocked_route_gate_count"] == 1 + assert data["rollups"]["blocked_receipt_count"] == 1 + assert data["rollups"]["owner_approval_received_count"] == 0 + assert data["rollups"]["gateway_queue_write_count"] == 0 + assert data["rollups"]["telegram_send_count"] == 0 + assert data["rollups"]["bot_api_call_count"] == 0 + assert data["rollups"]["report_receipt_write_count"] == 0 + assert data["rollups"]["ai_analysis_run_count"] == 0 + assert data["rollups"]["auto_optimization_count"] == 0 + assert data["rollups"]["production_write_count"] == 0 + + +def test_rejects_telegram_send_enabled(tmp_path): + data = load_latest_ai_agent_report_live_delivery_approval_package() + bad = copy.deepcopy(data) + bad["delivery_approval_truth"]["telegram_send_enabled"] = True + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="live send/write flags"): + load_latest_ai_agent_report_live_delivery_approval_package(tmp_path) + + +def test_rejects_gateway_queue_write_count(tmp_path): + data = load_latest_ai_agent_report_live_delivery_approval_package() + bad = copy.deepcopy(data) + bad["delivery_approval_truth"]["gateway_queue_write_count_24h"] = 1 + bad["rollups"]["gateway_queue_write_count"] = 1 + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="live counters"): + load_latest_ai_agent_report_live_delivery_approval_package(tmp_path) + + +def test_rejects_packet_send_mode(tmp_path): + data = load_latest_ai_agent_report_live_delivery_approval_package() + bad = copy.deepcopy(data) + bad["delivery_approval_packets"][0]["no_send_mode"] = False + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="no_send_mode"): + load_latest_ai_agent_report_live_delivery_approval_package(tmp_path) + + +def test_rejects_route_gate_send_enabled(tmp_path): + data = load_latest_ai_agent_report_live_delivery_approval_package() + bad = copy.deepcopy(data) + bad["route_lock_gates"][0]["telegram_send_enabled"] = True + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="telegram_send_enabled"): + load_latest_ai_agent_report_live_delivery_approval_package(tmp_path) + + +def test_rejects_redaction_display_allowed(tmp_path): + data = load_latest_ai_agent_report_live_delivery_approval_package() + bad = copy.deepcopy(data) + bad["payload_redaction_checks"][0]["display_allowed"] = True + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="display_allowed"): + load_latest_ai_agent_report_live_delivery_approval_package(tmp_path) + + +def test_rejects_receipt_write_allowed(tmp_path): + data = load_latest_ai_agent_report_live_delivery_approval_package() + bad = copy.deepcopy(data) + bad["dry_run_delivery_receipts"][0]["receipt_write_allowed"] = True + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="receipt_write_allowed"): + load_latest_ai_agent_report_live_delivery_approval_package(tmp_path) + + +def test_rejects_forbidden_display_terms(tmp_path): + data = load_latest_ai_agent_report_live_delivery_approval_package() + bad = copy.deepcopy(data) + bad["operator_actions"][0]["operator_instruction"] = "不得顯示工作視窗內容" + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="forbidden display terms"): + load_latest_ai_agent_report_live_delivery_approval_package(tmp_path) + + +def test_rejects_rollup_mismatch(tmp_path): + data = load_latest_ai_agent_report_live_delivery_approval_package() + bad = copy.deepcopy(data) + bad["rollups"]["delivery_approval_packet_count"] = 999 + _write_snapshot(tmp_path, bad) + + with pytest.raises(ValueError, match="rollup counts"): + load_latest_ai_agent_report_live_delivery_approval_package(tmp_path) diff --git a/apps/api/tests/test_ai_agent_report_live_delivery_approval_package_api.py b/apps/api/tests/test_ai_agent_report_live_delivery_approval_package_api.py new file mode 100644 index 00000000..f0a3ef8a --- /dev/null +++ b/apps/api/tests/test_ai_agent_report_live_delivery_approval_package_api.py @@ -0,0 +1,50 @@ +from fastapi.testclient import TestClient + +from src.main import app + + +def test_get_ai_agent_report_live_delivery_approval_package_api(): + client = TestClient(app) + response = client.get("/api/v1/agents/agent-report-live-delivery-approval-package") + + assert response.status_code == 200 + data = response.json() + assert data["schema_version"] == "ai_agent_report_live_delivery_approval_package_v1" + assert data["program_status"]["current_task_id"] == "P2-111" + assert data["program_status"]["next_task_id"] == "P2-112" + assert data["program_status"]["overall_completion_percent"] == 100 + assert data["prior_report_status_board"]["source_schema_version"] == "ai_agent_report_status_board_v1" + assert data["prior_report_status_board"]["report_card_count"] == 3 + assert data["prior_report_status_board"]["work_units_total"] == 91 + assert data["prior_runtime_review"]["approval_package_schema_version"] == "ai_agent_runtime_readback_approval_package_v1" + assert data["prior_runtime_review"]["implementation_review_schema_version"] == "ai_agent_runtime_readback_implementation_review_v1" + assert data["delivery_approval_truth"]["delivery_approval_package_ready"] is True + assert data["delivery_approval_truth"]["sre_war_room_route_locked"] is True + assert data["delivery_approval_truth"]["payload_redaction_ready"] is True + assert data["delivery_approval_truth"]["dry_run_receipt_ready"] is True + assert data["delivery_approval_truth"]["scheduler_enabled"] is False + assert data["delivery_approval_truth"]["gateway_queue_write_enabled"] is False + assert data["delivery_approval_truth"]["telegram_send_enabled"] is False + assert data["delivery_approval_truth"]["bot_api_call_enabled"] is False + assert data["delivery_approval_truth"]["report_receipt_write_enabled"] is False + assert data["delivery_approval_truth"]["ai_analysis_run_enabled"] is False + assert data["delivery_approval_truth"]["scheduled_delivery_count_24h"] == 0 + assert data["delivery_approval_truth"]["telegram_send_count_24h"] == 0 + assert data["rollups"]["delivery_approval_packet_count"] == 5 + assert data["rollups"]["route_lock_gate_count"] == 4 + assert data["rollups"]["payload_redaction_check_count"] == 5 + assert data["rollups"]["dry_run_delivery_receipt_count"] == 4 + assert data["rollups"]["operator_action_count"] == 5 + assert data["rollups"]["approval_required_packet_count"] == 3 + assert data["rollups"]["blocked_packet_count"] == 1 + assert data["rollups"]["blocked_route_gate_count"] == 1 + assert data["rollups"]["blocked_receipt_count"] == 1 + assert data["rollups"]["owner_approval_received_count"] == 0 + assert data["rollups"]["scheduled_delivery_count"] == 0 + assert data["rollups"]["gateway_queue_write_count"] == 0 + assert data["rollups"]["telegram_send_count"] == 0 + assert data["rollups"]["bot_api_call_count"] == 0 + assert data["rollups"]["report_receipt_write_count"] == 0 + assert data["rollups"]["ai_analysis_run_count"] == 0 + assert data["rollups"]["auto_optimization_count"] == 0 + assert data["rollups"]["production_write_count"] == 0 diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 83a29095..4b02d4d4 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -5075,6 +5075,95 @@ "review_failure_receipt_mapping": "審查失敗收據", "reject_or_promote": "退回或推進" } + }, + "reportLiveDeliveryApprovalPackage": { + "title": "P2-111 report live delivery 批准包", + "source": "{generated} · {current} → {next}", + "truthTitle": "實發批准真相", + "priorReportTitle": "P2-108 報表狀態承接", + "metrics": { + "overall": "P2-111 進度", + "packets": "批准包", + "routeGates": "route gate", + "redactionChecks": "遮蔽檢查", + "receipts": "no-send receipt", + "actions": "操作選項", + "approvalRequired": "需批准", + "blocked": "阻擋總數", + "ownerApprovals": "已收批准", + "scheduled": "排程實發", + "gatewayWrites": "Gateway queue", + "telegramSends": "Telegram 發送", + "botCalls": "Bot API", + "receiptWrites": "回執寫入", + "aiAnalysisRuns": "AI 分析", + "autoOptimizations": "自動優化", + "liveWrites": "正式寫入" + }, + "flags": { + "packageReady": "批准包 ready: {value}", + "routeLocked": "SRE route lock: {value}", + "redactionReady": "遮蔽 ready: {value}", + "dryRunReceipt": "no-send receipt: {value}", + "scheduler": "scheduler: {value}", + "gatewayWrite": "Gateway queue: {value}", + "telegramSend": "Telegram 發送: {value}", + "botApi": "Bot API: {value}", + "receiptWrite": "回執寫入: {value}", + "aiAnalysis": "AI 分析: {value}" + }, + "labels": { + "approvalFields": "批准欄位 {count}", + "blockedActions": "阻擋動作 {count}", + "noSendMode": "no-send: {value}", + "requiredEvidence": "必備證據 {count}", + "blockedRoutes": "阻擋路由 {count}", + "telegramSend": "Telegram: {value}", + "botApi": "Bot API: {value}", + "gatewayWrite": "Gateway: {value}", + "displayAllowed": "可顯示: {value}", + "requiredFields": "必填欄位 {count}", + "liveSendCount": "實發 {count}", + "receiptWrite": "回執寫入: {value}", + "liveSendAllowed": "允許實發: {value}" + }, + "packetStatuses": { + "ready_for_owner_review": "待 owner 審查", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "gateStatuses": { + "ready_for_owner_review": "待 owner 審查", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "checkStatuses": { + "ready": "可審查", + "blocked_by_policy": "政策阻擋" + }, + "receiptStatuses": { + "ready_for_owner_review": "待 owner 審查", + "blocked_by_policy": "政策阻擋" + }, + "cadences": { + "daily": "日報", + "weekly": "週報", + "monthly": "月報", + "failure_only": "失敗限定", + "receipt": "讀報回執" + }, + "riskTiers": { + "medium": "中風險", + "high": "高風險", + "critical": "關鍵阻擋" + }, + "actionTypes": { + "review_delivery_packet": "審查實發包", + "validate_sre_route": "核對 SRE 路由", + "validate_payload_redaction": "確認遮蔽", + "validate_zero_send_counters": "確認零實發", + "reject_or_promote": "退回或推進" + } } } }, diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 83a29095..4b02d4d4 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -5075,6 +5075,95 @@ "review_failure_receipt_mapping": "審查失敗收據", "reject_or_promote": "退回或推進" } + }, + "reportLiveDeliveryApprovalPackage": { + "title": "P2-111 report live delivery 批准包", + "source": "{generated} · {current} → {next}", + "truthTitle": "實發批准真相", + "priorReportTitle": "P2-108 報表狀態承接", + "metrics": { + "overall": "P2-111 進度", + "packets": "批准包", + "routeGates": "route gate", + "redactionChecks": "遮蔽檢查", + "receipts": "no-send receipt", + "actions": "操作選項", + "approvalRequired": "需批准", + "blocked": "阻擋總數", + "ownerApprovals": "已收批准", + "scheduled": "排程實發", + "gatewayWrites": "Gateway queue", + "telegramSends": "Telegram 發送", + "botCalls": "Bot API", + "receiptWrites": "回執寫入", + "aiAnalysisRuns": "AI 分析", + "autoOptimizations": "自動優化", + "liveWrites": "正式寫入" + }, + "flags": { + "packageReady": "批准包 ready: {value}", + "routeLocked": "SRE route lock: {value}", + "redactionReady": "遮蔽 ready: {value}", + "dryRunReceipt": "no-send receipt: {value}", + "scheduler": "scheduler: {value}", + "gatewayWrite": "Gateway queue: {value}", + "telegramSend": "Telegram 發送: {value}", + "botApi": "Bot API: {value}", + "receiptWrite": "回執寫入: {value}", + "aiAnalysis": "AI 分析: {value}" + }, + "labels": { + "approvalFields": "批准欄位 {count}", + "blockedActions": "阻擋動作 {count}", + "noSendMode": "no-send: {value}", + "requiredEvidence": "必備證據 {count}", + "blockedRoutes": "阻擋路由 {count}", + "telegramSend": "Telegram: {value}", + "botApi": "Bot API: {value}", + "gatewayWrite": "Gateway: {value}", + "displayAllowed": "可顯示: {value}", + "requiredFields": "必填欄位 {count}", + "liveSendCount": "實發 {count}", + "receiptWrite": "回執寫入: {value}", + "liveSendAllowed": "允許實發: {value}" + }, + "packetStatuses": { + "ready_for_owner_review": "待 owner 審查", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "gateStatuses": { + "ready_for_owner_review": "待 owner 審查", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "checkStatuses": { + "ready": "可審查", + "blocked_by_policy": "政策阻擋" + }, + "receiptStatuses": { + "ready_for_owner_review": "待 owner 審查", + "blocked_by_policy": "政策阻擋" + }, + "cadences": { + "daily": "日報", + "weekly": "週報", + "monthly": "月報", + "failure_only": "失敗限定", + "receipt": "讀報回執" + }, + "riskTiers": { + "medium": "中風險", + "high": "高風險", + "critical": "關鍵阻擋" + }, + "actionTypes": { + "review_delivery_packet": "審查實發包", + "validate_sre_route": "核對 SRE 路由", + "validate_payload_redaction": "確認遮蔽", + "validate_zero_send_counters": "確認零實發", + "reject_or_promote": "退回或推進" + } } } }, 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 d72836fc..e3ed15a6 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 AiAgentReportLiveDeliveryApprovalPackageSnapshot, type AiAgentReportStatusBoardSnapshot, type AiAgentReportRuntimeDryRunSnapshot, type AiAgentReportRuntimeFixtureReadbackSnapshot, @@ -438,6 +439,7 @@ export function AutomationInventoryTab() { const [ownerApprovedResultCaptureReadback, setOwnerApprovedResultCaptureReadback] = useState(null) const [runtimeReadbackApprovalPackage, setRuntimeReadbackApprovalPackage] = useState(null) const [runtimeReadbackImplementationReview, setRuntimeReadbackImplementationReview] = useState(null) + const [reportLiveDeliveryApprovalPackage, setReportLiveDeliveryApprovalPackage] = useState(null) const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState(null) const [ownerDryRunPackage, setOwnerDryRunPackage] = useState(null) const [hostStatefulInventory, setHostStatefulInventory] = useState(null) @@ -485,6 +487,7 @@ export function AutomationInventoryTab() { apiClient.getAiAgentOwnerApprovedResultCaptureReadback(), apiClient.getAiAgentRuntimeReadbackApprovalPackage(), apiClient.getAiAgentRuntimeReadbackImplementationReview(), + apiClient.getAiAgentReportLiveDeliveryApprovalPackage(), apiClient.getAiAgentReportTruthActionabilityReview(), apiClient.getAiAgentOwnerApprovedFixtureDryRun(), apiClient.getAiAgentHostStatefulVersionInventory(), @@ -531,6 +534,7 @@ export function AutomationInventoryTab() { ownerApprovedResultCaptureReadbackResult, runtimeReadbackApprovalPackageResult, runtimeReadbackImplementationReviewResult, + reportLiveDeliveryApprovalPackageResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -574,6 +578,7 @@ export function AutomationInventoryTab() { setOwnerApprovedResultCaptureReadback(ownerApprovedResultCaptureReadbackResult.status === 'fulfilled' ? ownerApprovedResultCaptureReadbackResult.value : null) setRuntimeReadbackApprovalPackage(runtimeReadbackApprovalPackageResult.status === 'fulfilled' ? runtimeReadbackApprovalPackageResult.value : null) setRuntimeReadbackImplementationReview(runtimeReadbackImplementationReviewResult.status === 'fulfilled' ? runtimeReadbackImplementationReviewResult.value : null) + setReportLiveDeliveryApprovalPackage(reportLiveDeliveryApprovalPackageResult.status === 'fulfilled' ? reportLiveDeliveryApprovalPackageResult.value : null) setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null) setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null) setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null) @@ -615,6 +620,7 @@ export function AutomationInventoryTab() { ownerApprovedResultCaptureReadbackResult, runtimeReadbackApprovalPackageResult, runtimeReadbackImplementationReviewResult, + reportLiveDeliveryApprovalPackageResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -1595,6 +1601,49 @@ export function AutomationInventoryTab() { .slice(0, 5) }, [runtimeReadbackImplementationReview]) + const visibleReportDeliveryPackets = useMemo(() => { + if (!reportLiveDeliveryApprovalPackage) return [] + const statusPriority = { blocked_by_policy: 0, approval_required: 1, ready_for_owner_review: 2 } as Record + const riskPriority = { critical: 0, high: 1, medium: 2 } as Record + return [...reportLiveDeliveryApprovalPackage.delivery_approval_packets] + .sort((a, b) => { + const leftStatus = statusPriority[a.status] ?? 3 + const rightStatus = statusPriority[b.status] ?? 3 + if (leftStatus !== rightStatus) return leftStatus - rightStatus + const leftRisk = riskPriority[a.risk_tier] ?? 4 + const rightRisk = riskPriority[b.risk_tier] ?? 4 + if (leftRisk !== rightRisk) return leftRisk - rightRisk + return a.packet_id.localeCompare(b.packet_id) + }) + .slice(0, 5) + }, [reportLiveDeliveryApprovalPackage]) + + const visibleReportRouteGates = useMemo(() => { + if (!reportLiveDeliveryApprovalPackage) return [] + const statusPriority = { blocked_by_policy: 0, approval_required: 1, ready_for_owner_review: 2 } as Record + return [...reportLiveDeliveryApprovalPackage.route_lock_gates] + .sort((a, b) => { + const left = statusPriority[a.status] ?? 3 + const right = statusPriority[b.status] ?? 3 + if (left !== right) return left - right + return a.gate_id.localeCompare(b.gate_id) + }) + .slice(0, 4) + }, [reportLiveDeliveryApprovalPackage]) + + const visibleReportDeliveryReceipts = useMemo(() => { + if (!reportLiveDeliveryApprovalPackage) return [] + const statusPriority = { blocked_by_policy: 0, ready_for_owner_review: 1 } as Record + return [...reportLiveDeliveryApprovalPackage.dry_run_delivery_receipts] + .sort((a, b) => { + const left = statusPriority[a.status] ?? 2 + const right = statusPriority[b.status] ?? 2 + if (left !== right) return left - right + return a.receipt_id.localeCompare(b.receipt_id) + }) + .slice(0, 4) + }, [reportLiveDeliveryApprovalPackage]) + const visibleReportTruthFindings = useMemo(() => { if (!reportTruthActionabilityReview) return [] const priority = { critical: 0, high: 1, medium: 2, low: 3 } as Record @@ -1814,7 +1863,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 || !reportStatusBoard || !reportRuntimeReadiness || !reportRuntimeDryRun || !reportRuntimeFixtureReadback || !runtimeWorkerShadowGate || !operationPermissionModel || !candidateOperationDryRunEvidence || !taskResultAuditTrail || !matchedPlaybookLearningGap || !criticReviewerResultCapture || !ownerApprovedResultCaptureDryRun || !ownerApprovedResultCaptureReadback || !runtimeReadbackApprovalPackage || !runtimeReadbackImplementationReview || !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 || !runtimeReadbackApprovalPackage || !runtimeReadbackImplementationReview || !reportLiveDeliveryApprovalPackage || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { return (
@@ -2193,6 +2242,35 @@ export function AutomationInventoryTab() { + runtimeReadbackImplementationReview.rollups.rollback_work_item_write_count + runtimeReadbackImplementationReview.rollups.production_write_count ) + const reportDeliveryOverall = reportLiveDeliveryApprovalPackage.program_status.overall_completion_percent + const reportDeliveryPackets = reportLiveDeliveryApprovalPackage.rollups.delivery_approval_packet_count + const reportDeliveryRouteGates = reportLiveDeliveryApprovalPackage.rollups.route_lock_gate_count + const reportDeliveryRedactionChecks = reportLiveDeliveryApprovalPackage.rollups.payload_redaction_check_count + const reportDeliveryReceipts = reportLiveDeliveryApprovalPackage.rollups.dry_run_delivery_receipt_count + const reportDeliveryActions = reportLiveDeliveryApprovalPackage.rollups.operator_action_count + const reportDeliveryApprovalRequired = reportLiveDeliveryApprovalPackage.rollups.approval_required_packet_count + const reportDeliveryBlocked = ( + reportLiveDeliveryApprovalPackage.rollups.blocked_packet_count + + reportLiveDeliveryApprovalPackage.rollups.blocked_route_gate_count + + reportLiveDeliveryApprovalPackage.rollups.blocked_receipt_count + ) + const reportDeliveryOwnerApprovals = reportLiveDeliveryApprovalPackage.rollups.owner_approval_received_count + const reportDeliveryScheduled = reportLiveDeliveryApprovalPackage.rollups.scheduled_delivery_count + const reportDeliveryGatewayWrites = reportLiveDeliveryApprovalPackage.rollups.gateway_queue_write_count + const reportDeliveryTelegramSends = reportLiveDeliveryApprovalPackage.rollups.telegram_send_count + const reportDeliveryBotCalls = reportLiveDeliveryApprovalPackage.rollups.bot_api_call_count + const reportDeliveryReceiptWrites = reportLiveDeliveryApprovalPackage.rollups.report_receipt_write_count + const reportDeliveryAiAnalysisRuns = reportLiveDeliveryApprovalPackage.rollups.ai_analysis_run_count + const reportDeliveryAutoOptimizations = reportLiveDeliveryApprovalPackage.rollups.auto_optimization_count + const reportDeliveryLiveWrites = ( + reportLiveDeliveryApprovalPackage.rollups.gateway_queue_write_count + + reportLiveDeliveryApprovalPackage.rollups.telegram_send_count + + reportLiveDeliveryApprovalPackage.rollups.bot_api_call_count + + reportLiveDeliveryApprovalPackage.rollups.report_receipt_write_count + + reportLiveDeliveryApprovalPackage.rollups.ai_analysis_run_count + + reportLiveDeliveryApprovalPackage.rollups.auto_optimization_count + + reportLiveDeliveryApprovalPackage.rollups.production_write_count + ) const reportTruthOverall = reportTruthActionabilityReview.program_status.overall_completion_percent const reportTruthFindings = reportTruthActionabilityReview.rollups.zero_signal_finding_count const reportTruthCritical = reportTruthActionabilityReview.rollups.critical_finding_count @@ -5300,6 +5378,182 @@ export function AutomationInventoryTab() {
+
+
+
+ + + {t('reportLiveDeliveryApprovalPackage.title')} + +
+ +
+ +
+ } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> +
+ +
+
+ {t('reportLiveDeliveryApprovalPackage.priorReportTitle')} + + {reportLiveDeliveryApprovalPackage.prior_report_status_board.readiness_note} + +
+ + + + +
+
+ +
+ {t('reportLiveDeliveryApprovalPackage.truthTitle')} + + {reportLiveDeliveryApprovalPackage.delivery_approval_truth.truth_note} + +
+ + + + + + + + + + +
+
+
+ +
+ {visibleReportDeliveryPackets.map(packet => ( +
+
+ + {packet.display_name} + + +
+ + {packet.operator_guidance} + +
+ + + + + + +
+
+ ))} +
+ +
+ {visibleReportRouteGates.map(gate => ( +
+
+ + {gate.display_name} + + +
+
+ + + + + +
+
+ ))} +
+ +
+ {reportLiveDeliveryApprovalPackage.payload_redaction_checks.map(check => ( +
+
+ + {check.display_name} + + +
+ + {check.failure_if_missing} + +
+ + +
+
+ ))} +
+ +
+ {visibleReportDeliveryReceipts.map(receipt => ( +
+
+ + {receipt.display_name} + + +
+
+ + + + +
+
+ ))} +
+ +
+ {reportLiveDeliveryApprovalPackage.operator_actions.map(action => ( +
+
+ + {action.display_name} + + +
+ + {action.operator_instruction} + +
+ + +
+
+ ))} +
+
+
diff --git a/apps/web/src/lib/api-client.ts b/apps/web/src/lib/api-client.ts index 4ba241af..f82d1e86 100644 --- a/apps/web/src/lib/api-client.ts +++ b/apps/web/src/lib/api-client.ts @@ -450,6 +450,11 @@ export const apiClient = { return handleResponse(res) }, + async getAiAgentReportLiveDeliveryApprovalPackage() { + const res = await fetch(`${API_BASE_URL}/agents/agent-report-live-delivery-approval-package`) + return handleResponse(res) + }, + async getAiAgentOwnerApprovedFixtureDryRun() { const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`) return handleResponse(res) @@ -4135,6 +4140,169 @@ export interface AiAgentRuntimeReadbackImplementationReviewSnapshot { } } +export interface AiAgentReportLiveDeliveryApprovalPackageSnapshot { + schema_version: 'ai_agent_report_live_delivery_approval_package_v1' + generated_at: string + program_status: { + overall_completion_percent: number + current_priority: 'P0' | 'P1' | 'P2' | 'P3' + current_task_id: 'P2-111' + next_task_id: 'P2-112' + read_only_mode: true + runtime_authority: 'report_live_delivery_approval_package_only_no_live_send_or_write' + status_note: string + } + source_refs: string[] + prior_report_status_board: { + source_schema_version: 'ai_agent_report_status_board_v1' + readback_at: string + report_card_count: number + agent_status_report_count: number + visible_chart_count: number + operator_answer_count: number + work_units_total: number + work_units_done: number + work_units_waiting_approval: number + live_delivery_count: number + live_telegram_send_count_24h: number + live_auto_optimization_count_24h: number + readiness_note: string + } + prior_runtime_review: { + approval_package_schema_version: 'ai_agent_runtime_readback_approval_package_v1' + implementation_review_schema_version: 'ai_agent_runtime_readback_implementation_review_v1' + telegram_failure_receipt_gate_count: number + implementation_blocker_count: number + no_write_verifier_check_count: number + owner_approval_received_count: number + runtime_readback_execution_count: number + live_query_count: number + telegram_failure_receipt_send_count: number + bot_api_call_count: number + gateway_queue_write_count: number + production_write_count: number + readiness_note: string + } + delivery_approval_truth: { + p2_108_report_status_loaded: true + p2_109_failure_receipt_gate_loaded: true + p2_110_implementation_review_loaded: true + delivery_approval_package_ready: true + daily_delivery_package_ready: true + weekly_delivery_package_ready: true + monthly_delivery_package_ready: true + sre_war_room_route_locked: true + payload_redaction_ready: true + dry_run_receipt_ready: true + owner_review_required_before_delivery: true + scheduler_enabled: false + gateway_queue_write_enabled: false + telegram_send_enabled: false + bot_api_call_enabled: false + report_receipt_write_enabled: false + ai_analysis_run_enabled: false + medium_low_auto_optimization_enabled: false + production_write_enabled: false + secret_read_enabled: false + destructive_operation_enabled: false + owner_approval_received_count: number + scheduled_delivery_count_24h: number + gateway_queue_write_count_24h: number + telegram_send_count_24h: number + bot_api_call_count_24h: number + report_receipt_write_count_24h: number + ai_analysis_run_count_24h: number + auto_optimization_count_24h: number + production_write_count_24h: number + secret_read_count_24h: number + destructive_operation_count_24h: number + truth_note: string + } + delivery_approval_packets: Array<{ + packet_id: string + display_name: string + cadence: 'daily' | 'weekly' | 'monthly' | 'failure_only' | 'receipt' + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + status: 'approval_required' | 'ready_for_owner_review' | 'blocked_by_policy' + risk_tier: 'medium' | 'high' | 'critical' + required_approval_fields: string[] + blocked_runtime_actions: string[] + operator_guidance: string + approval_required: true + no_send_mode: true + evidence_hash: string + }> + route_lock_gates: Array<{ + gate_id: string + display_name: string + status: 'ready_for_owner_review' | 'approval_required' | 'blocked_by_policy' + required_evidence: string[] + blocked_routes: string[] + telegram_send_enabled: false + bot_api_call_enabled: false + gateway_queue_write_enabled: false + evidence_hash: string + }> + payload_redaction_checks: Array<{ + check_id: string + display_name: string + status: 'ready' | 'blocked_by_policy' + required_rule: string + failure_if_missing: string + display_allowed: false + evidence_hash: string + }> + dry_run_delivery_receipts: Array<{ + receipt_id: string + display_name: string + cadence: 'daily' | 'weekly' | 'monthly' | 'failure_only' | 'receipt' + status: 'ready_for_owner_review' | 'blocked_by_policy' + required_fields: string[] + live_send_count: number + receipt_write_allowed: false + evidence_hash: string + }> + operator_actions: Array<{ + action_id: string + action_type: 'review_delivery_packet' | 'validate_sre_route' | 'validate_payload_redaction' | 'validate_zero_send_counters' | 'reject_or_promote' + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + operator_instruction: string + live_send_allowed: false + }> + display_redaction_contract: { + redaction_required: true + frontend_display_policy: string + raw_prompt_display_allowed: false + private_reasoning_display_allowed: false + secret_value_display_allowed: false + raw_telegram_payload_display_allowed: false + internal_collaboration_content_display_allowed: false + } + rollups: { + delivery_approval_packet_count: number + route_lock_gate_count: number + payload_redaction_check_count: number + dry_run_delivery_receipt_count: number + operator_action_count: number + approval_required_packet_count: number + blocked_packet_count: number + blocked_route_gate_count: number + blocked_receipt_count: number + owner_approval_received_count: number + scheduled_delivery_count: number + gateway_queue_write_count: number + telegram_send_count: number + bot_api_call_count: number + report_receipt_write_count: number + ai_analysis_run_count: number + auto_optimization_count: number + production_write_count: number + secret_read_count: number + destructive_operation_count: number + } +} + export interface AiAgentOwnerApprovedFixtureDryRunSnapshot { schema_version: 'ai_agent_owner_approved_fixture_dry_run_v1' generated_at: string diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 7aa6fbd1..ffd07bd4 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,26 @@ +## 2026-06-13|P2-111 Report live delivery approval package 本地完成 + +**背景**:P2-108 已讓日報 / 週報 / 月報與 Agent 工作量可見,P2-109 / P2-110 已把 runtime readback approval package 與 implementation review 固定成 no-write gate;但週報全 0、Telegram 未實發與 AwoooI SRE 戰情室收斂仍缺少一個可審查的「實發批准包」。 + +**完成內容**: +- 新增 `ai_agent_report_live_delivery_approval_package_v1` schema、committed snapshot、loader 與 API endpoint `GET /api/v1/agents/agent-report-live-delivery-approval-package`。 +- P2-111 snapshot 固定 5 個 report delivery approval packet、4 個 route lock gate、5 個 payload redaction check、4 個 no-send delivery receipt 與 5 個 operator action。 +- Governance automation inventory 頁新增 P2-111 區塊,顯示 P2-111 進度 `100%`、批准包 `5`、route gate `4`、遮蔽檢查 `5`、no-send receipt `4`、操作選項 `5`、需批准 `3`、阻擋總數 `3`、owner approval received `0`、scheduler `0`、Gateway queue `0`、Telegram send `0`、Bot API `0`、report receipt write `0`、AI analysis `0`、auto optimization `0` 與 live writes `0`。 +- 更新 MASTER §3.2 / §5、`docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md` 與 `docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md`,下一步改為 `P2-112` runtime readback fixture approval。 + +**本地驗證**: +- JSON parse:P2-111 schema / snapshot、`zh-TW.json`、`en.json` 通過。 +- API/service pytest:P2-108 / P2-109 / P2-110 / P2-111 目標組 `37 passed`。 +- i18n mirror / placeholder:`10884` leaves,diff `0`。 +- Web typecheck:`pnpm --filter @awoooi/web typecheck` 通過。 +- `source-control-owner-response-guard.py`、`security-mirror-progress-guard.py`、`git diff --check` 通過。 + +**安全邊界**: +- P2-111 仍是只讀實發批准包;不排程、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不啟動 AI analysis、不啟動中低風險 auto worker、不寫 production target、不讀 secret、不執行 destructive action、不回傳內部協作內容。 + +**下一步**: +- 推送 Gitea main 後等待 CD deploy marker,對 `GET /api/v1/agents/agent-report-live-delivery-approval-package` 與 `/zh-TW/governance?tab=automation-inventory` 做正式 API readback 與 desktop / mobile browser smoke。 + ## 2026-06-13|P2-110 Runtime readback implementation review 本地完成與正式驗證 **背景**:P2-109 已把 runtime readback 拆成批准包、canonical readback plan、rollback drill 與 Telegram failure receipt gate;但仍缺少「批准包要如何被實作審查」的 no-write 介面、verifier、阻塞原因與人工下一步。 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 c0651bb9..086d8290 100644 --- a/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md +++ b/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md @@ -12,7 +12,7 @@ | 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;P2-108 已完成日週月報與 Agent 工作狀態總覽;P2-109 已完成 runtime readback approval package;P2-110 已完成 runtime readback implementation review 並正式驗證,固定 5 張實作卡、5 個 no-write verifier、5 個阻塞項與 5 個 operator action。runtime worker、DB migration、production Redis consumer group、canonical runtime readback、live query、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`、`ai_agent_runtime_readback_approval_package_v1`、`ai_agent_runtime_readback_implementation_review_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`、`GET /api/v1/agents/agent-runtime-readback-approval-package`、`GET /api/v1/agents/agent-runtime-readback-implementation-review`、`/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 工作狀態總覽;P2-109 已完成 runtime readback approval package;P2-110 已完成 runtime readback implementation review 並正式驗證;P2-111 已本地完成 report live delivery approval package,固定 5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt 與 5 個 operator action。runtime worker、DB migration、production Redis consumer group、canonical runtime readback、live query、runtime score、result capture write、Telegram 實發、delivery receipt E2E、live 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`、`ai_agent_runtime_readback_approval_package_v1`、`ai_agent_runtime_readback_implementation_review_v1`、`ai_agent_report_live_delivery_approval_package_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`、`GET /api/v1/agents/agent-runtime-readback-approval-package`、`GET /api/v1/agents/agent-runtime-readback-implementation-review`、`GET /api/v1/agents/agent-report-live-delivery-approval-package`、`/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 文件 | @@ -20,9 +20,9 @@ AI Agent 自動化工作包目前完成度:**94%**。本工作清單文件本 三 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-108 日週月報與 Agent 工作狀態總覽、P2-109 runtime readback approval package,以及 P2-110 runtime readback implementation review 正式驗證。目前 live AgentSession、Agent message、handoff、canonical runtime readback、live query、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-110 已固定 5 張實作卡、5 個 no-write verifier、5 個阻塞項與 5 個 operator action;真正下一步是 `P2-111`。 +三 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 工作狀態總覽、P2-109 runtime readback approval package、P2-110 runtime readback implementation review 正式驗證,以及 P2-111 report live delivery approval package 本地完成。目前 live AgentSession、Agent message、handoff、canonical runtime readback、live query、runtime score、result capture write、learning write、Telegram receipt、Gateway queue write、reviewer queue write、runtime verifier execution、live report delivery、AI analysis runtime、中低風險 auto worker、Telegram 實發、shadow worker live、delivery receipt E2E、KM / LOGBOOK / audit DB / timeline / PlayBook trust runtime 寫入仍全部為 `0`。P2-111 已固定 5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt 與 5 個 operator action;真正下一步是 `P2-112`。 -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-110` 已補互動、學習證據面、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、runtime readback approval package 與 runtime readback implementation review。下一步是 `P2-111`;外部 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-111` 已補互動、學習證據面、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、runtime readback approval package、runtime readback implementation review 與 report live delivery approval package。下一步是 `P2-112`;外部 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 794d6fb8..60e0dbe4 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、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、不執行生產優化、不顯示內部協作內容。 +> 文件定位: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 工作狀態總覽、P2-111 report live delivery approval package、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 與 report live delivery approval package,不啟動 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、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 與日週月報工作狀態總覽。 +已完成 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、P2-109、P2-110 與 P2-111:讓統帥能在治理頁看到 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、日週月報工作狀態總覽、runtime readback approval / implementation review,以及 report live delivery approval package。 目前真相: @@ -95,6 +95,9 @@ | 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` | +| P2-109 runtime readback approval package | 已完成,5 個批准包、4 個 canonical readback plan、4 條 rollback drill、4 個 Telegram failure receipt gate;runtime readback / queue / send / write 全為 `0` | +| P2-110 runtime readback implementation review | 已完成,5 張 implementation review card、5 個 no-write verifier、5 個 blocker、5 個 operator action;live query / runtime execution / production write 全為 `0` | +| P2-111 report live delivery approval package | 已本地完成,5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt;scheduler / Gateway queue / Telegram send / Bot API / receipt write / AI analysis / auto optimization 全為 `0` | 這代表使用者現在可以看見「哪裡已準備好、哪裡仍未運作、被哪個 gate 阻擋、下一步要如何驗證」。但還不能宣稱三個 Agent 已經在 production runtime 主動互傳訊息或自主學習。 @@ -180,19 +183,21 @@ | `docs/evaluations/ai_agent_runtime_readback_approval_package_2026-06-13.json` | P2-109 committed snapshot,完成度 `100%`,5 個批准包、4 個 canonical readback plan、4 條 rollback drill、4 個 Telegram failure receipt gate、5 個 operator action;runtime readback execution、owner approval received 與所有 live write / send counts 全為 `0` | | `docs/schemas/ai_agent_runtime_readback_implementation_review_v1.schema.json` | P2-110 runtime readback implementation review schema;強制 canonical runtime readback、live query、runtime readback execution、owner approval received、reviewer queue write、Gateway queue、Telegram failure receipt、Bot API、rollback work item、production write、secret read 與 destructive action 維持未授權 | | `docs/evaluations/ai_agent_runtime_readback_implementation_review_2026-06-13.json` | P2-110 committed snapshot,完成度 `100%`,5 張 implementation review card、5 個 no-write verifier check、5 個 implementation blocker、5 個 operator action;live query、runtime readback execution、owner approval received 與所有 live write / send counts 全為 `0` | +| `docs/schemas/ai_agent_report_live_delivery_approval_package_v1.schema.json` | P2-111 report live delivery approval package schema;強制 scheduler、Gateway queue write、Telegram send、Bot API、report receipt write、AI analysis run、中低風險 auto optimization、production write、secret read 與 destructive action 維持未授權 | +| `docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json` | P2-111 committed snapshot,完成度 `100%`,5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt、5 個 operator action;scheduler、Gateway queue、Telegram send、Bot API、report receipt write、AI analysis、auto optimization 與所有 live write / send counts 全為 `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-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、P2-109 runtime readback approval package、P2-110 runtime readback implementation review、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、P2-109 runtime readback approval package、P2-110 runtime readback implementation review、P2-111 report live delivery approval package、Agent lane、可觀測訊號、runtime gates、前端 redaction | ## 5. 後續優先順序 | 優先 | ID | 工作 | gate | |---:|---|---|---| -| 1 | P2-111 | report live delivery approval package | 以 P2-108 report status board、P2-109 Telegram failure receipt gate 與 P2-110 no-write implementation review 產生下一關派送批准包,仍需維持 no live send / no live write | -| 2 | P2-112 | runtime readback fixture approval | 以 P2-110 implementation review 的 adapter contract / verifier check / blocker 產生下一關 fixture-only runtime readback approval,不讀 canonical runtime target | +| 1 | P2-112 | runtime readback fixture approval | 以 P2-111 report live delivery approval package、P2-110 implementation review 的 adapter contract / verifier check / blocker 產生下一關 fixture-only runtime readback approval,不讀 canonical runtime target | +| 2 | P2-113 | report delivery fixture readback | 只用 fixture / no-send receipt 回放報表實發鏈,仍不排程、不寫 Gateway queue、不送 Telegram | ## 6. 紅線 diff --git a/docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json b/docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json new file mode 100644 index 00000000..35a520c3 --- /dev/null +++ b/docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json @@ -0,0 +1,466 @@ +{ + "schema_version": "ai_agent_report_live_delivery_approval_package_v1", + "generated_at": "2026-06-13T17:18:00+08:00", + "program_status": { + "overall_completion_percent": 100, + "current_priority": "P2", + "current_task_id": "P2-111", + "next_task_id": "P2-112", + "read_only_mode": true, + "runtime_authority": "report_live_delivery_approval_package_only_no_live_send_or_write", + "status_note": "P2-111 承接 P2-108 報告狀態、P2-109 Telegram 失敗收據 gate 與 P2-110 implementation review,固定日報、週報、月報、失敗限定摘要與讀報回執的實發批准包;本快照不排程、不送 Telegram、不寫 Gateway queue、不呼叫 Bot API。" + }, + "source_refs": [ + "docs/evaluations/ai_agent_report_status_board_2026-06-13.json", + "docs/evaluations/ai_agent_runtime_readback_approval_package_2026-06-13.json", + "docs/evaluations/ai_agent_runtime_readback_implementation_review_2026-06-13.json", + "docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md" + ], + "prior_report_status_board": { + "source_schema_version": "ai_agent_report_status_board_v1", + "readback_at": "2026-06-13T15:08:00+08:00", + "report_card_count": 3, + "agent_status_report_count": 3, + "visible_chart_count": 3, + "operator_answer_count": 4, + "work_units_total": 91, + "work_units_done": 79, + "work_units_waiting_approval": 12, + "live_delivery_count": 0, + "live_telegram_send_count_24h": 0, + "live_auto_optimization_count_24h": 0, + "readiness_note": "P2-108 已讓日報、週報、月報與 Agent 工作量可見,但 delivery_state 仍是 draft_only;P2-111 只建立實發批准包,不排程實發。" + }, + "prior_runtime_review": { + "approval_package_schema_version": "ai_agent_runtime_readback_approval_package_v1", + "implementation_review_schema_version": "ai_agent_runtime_readback_implementation_review_v1", + "telegram_failure_receipt_gate_count": 4, + "implementation_blocker_count": 5, + "no_write_verifier_check_count": 5, + "owner_approval_received_count": 0, + "runtime_readback_execution_count": 0, + "live_query_count": 0, + "telegram_failure_receipt_send_count": 0, + "bot_api_call_count": 0, + "gateway_queue_write_count": 0, + "production_write_count": 0, + "readiness_note": "P2-109 / P2-110 已把 Telegram route、failure receipt 與 no-write verifier 固定;P2-111 只允許用它們產生 delivery approval package。" + }, + "delivery_approval_truth": { + "p2_108_report_status_loaded": true, + "p2_109_failure_receipt_gate_loaded": true, + "p2_110_implementation_review_loaded": true, + "delivery_approval_package_ready": true, + "daily_delivery_package_ready": true, + "weekly_delivery_package_ready": true, + "monthly_delivery_package_ready": true, + "sre_war_room_route_locked": true, + "payload_redaction_ready": true, + "dry_run_receipt_ready": true, + "owner_review_required_before_delivery": true, + "scheduler_enabled": false, + "gateway_queue_write_enabled": false, + "telegram_send_enabled": false, + "bot_api_call_enabled": false, + "report_receipt_write_enabled": false, + "ai_analysis_run_enabled": false, + "medium_low_auto_optimization_enabled": false, + "production_write_enabled": false, + "secret_read_enabled": false, + "destructive_operation_enabled": false, + "owner_approval_received_count": 0, + "scheduled_delivery_count_24h": 0, + "gateway_queue_write_count_24h": 0, + "telegram_send_count_24h": 0, + "bot_api_call_count_24h": 0, + "report_receipt_write_count_24h": 0, + "ai_analysis_run_count_24h": 0, + "auto_optimization_count_24h": 0, + "production_write_count_24h": 0, + "secret_read_count_24h": 0, + "destructive_operation_count_24h": 0, + "truth_note": "日週月報實發批准包已可審查;真正 scheduler、Gateway queue、Telegram send、Bot API、讀報回執、AI 分析與自動優化全部仍為 0。" + }, + "delivery_approval_packets": [ + { + "packet_id": "daily_report_delivery_approval", + "display_name": "AI Agent 日報實發批准包", + "cadence": "daily", + "owner_agent": "hermes", + "status": "approval_required", + "risk_tier": "medium", + "required_approval_fields": [ + "cadence", + "delivery_window", + "recipient_route", + "payload_redaction_ref", + "dedupe_fingerprint", + "owner_decision" + ], + "blocked_runtime_actions": [ + "scheduler_enable", + "gateway_queue_write", + "telegram_send" + ], + "operator_guidance": "日報實發前必須確認只送 AwoooI SRE 戰情室、payload 已遮蔽、dedupe 生效且失敗才升級人工。", + "approval_required": true, + "no_send_mode": true, + "evidence_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + { + "packet_id": "weekly_report_delivery_approval", + "display_name": "AI Agent 週報實發批准包", + "cadence": "weekly", + "owner_agent": "openclaw", + "status": "approval_required", + "risk_tier": "high", + "required_approval_fields": [ + "week_id", + "zero_signal_explanation", + "actionability_score", + "owner_summary", + "delivery_route", + "rollback_decision" + ], + "blocked_runtime_actions": [ + "scheduler_enable", + "telegram_send", + "ai_analysis_run", + "medium_low_auto_optimization" + ], + "operator_guidance": "週報若全部為 0,必須先說明資料鏈斷點與下一步,不得只發無用摘要。", + "approval_required": true, + "no_send_mode": true, + "evidence_hash": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + }, + { + "packet_id": "monthly_report_delivery_approval", + "display_name": "AI Agent 月報實發批准包", + "cadence": "monthly", + "owner_agent": "openclaw", + "status": "ready_for_owner_review", + "risk_tier": "high", + "required_approval_fields": [ + "month_id", + "strategic_findings", + "cost_summary", + "automation_gap_summary", + "owner_review_owner", + "publication_decision" + ], + "blocked_runtime_actions": [ + "telegram_send", + "report_receipt_write", + "production_optimization_write" + ], + "operator_guidance": "月報只能先形成策略摘要與成本缺口,未批准前不得實發或啟動生產優化。", + "approval_required": true, + "no_send_mode": true, + "evidence_hash": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + { + "packet_id": "failure_only_digest_approval", + "display_name": "失敗限定摘要批准包", + "cadence": "failure_only", + "owner_agent": "hermes", + "status": "approval_required", + "risk_tier": "high", + "required_approval_fields": [ + "failure_signal_type", + "route_lock", + "dedupe_ttl", + "next_manual_action", + "blocked_reason" + ], + "blocked_runtime_actions": [ + "telegram_send", + "bot_api_call", + "gateway_queue_write" + ], + "operator_guidance": "成功心跳與無事件週報不得洗版;只有失敗、卡點或資料鏈斷裂才可進入失敗限定通知審查。", + "approval_required": true, + "no_send_mode": true, + "evidence_hash": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + }, + { + "packet_id": "report_receipt_readback_approval", + "display_name": "讀報回執 readback 批准包", + "cadence": "receipt", + "owner_agent": "nemotron", + "status": "blocked_by_policy", + "risk_tier": "critical", + "required_approval_fields": [ + "receipt_id", + "delivery_packet_id", + "readback_plan_id", + "rollback_owner", + "owner_acceptance_record" + ], + "blocked_runtime_actions": [ + "report_receipt_write", + "ai_analysis_run", + "production_write" + ], + "operator_guidance": "讀報回執仍停在批准包層;沒有 acceptance record 前不得寫 receipt 或啟動讀報後 AI 分析。", + "approval_required": true, + "no_send_mode": true, + "evidence_hash": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + ], + "route_lock_gates": [ + { + "gate_id": "sre_war_room_route_lock", + "display_name": "AwoooI SRE 戰情室 route lock", + "status": "ready_for_owner_review", + "required_evidence": [ + "route_id", + "recipient_policy", + "legacy_route_blocklist" + ], + "blocked_routes": [ + "legacy_direct_bot", + "personal_chat", + "non_sre_group" + ], + "telegram_send_enabled": false, + "bot_api_call_enabled": false, + "gateway_queue_write_enabled": false, + "evidence_hash": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + { + "gate_id": "legacy_bot_suppression", + "display_name": "舊 Bot / 舊群組 suppression", + "status": "approval_required", + "required_evidence": [ + "legacy_bot_inventory", + "suppression_policy", + "fallback_route" + ], + "blocked_routes": [ + "unknown_telegram_bot", + "non_awoooi_sre_room" + ], + "telegram_send_enabled": false, + "bot_api_call_enabled": false, + "gateway_queue_write_enabled": false, + "evidence_hash": "sha256:2222222222222222222222222222222222222222222222222222222222222222" + }, + { + "gate_id": "dedupe_fingerprint_lock", + "display_name": "dedupe / fingerprint lock", + "status": "ready_for_owner_review", + "required_evidence": [ + "dedupe_key", + "fingerprint_fields", + "recurrence_window" + ], + "blocked_routes": [ + "duplicate_digest_send" + ], + "telegram_send_enabled": false, + "bot_api_call_enabled": false, + "gateway_queue_write_enabled": false, + "evidence_hash": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + }, + { + "gate_id": "delivery_window_gate", + "display_name": "delivery window gate", + "status": "blocked_by_policy", + "required_evidence": [ + "timezone", + "quiet_hours", + "failure_only_bypass" + ], + "blocked_routes": [ + "quiet_hour_digest", + "success_heartbeat_spam" + ], + "telegram_send_enabled": false, + "bot_api_call_enabled": false, + "gateway_queue_write_enabled": false, + "evidence_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + } + ], + "payload_redaction_checks": [ + { + "check_id": "no_raw_prompt", + "display_name": "不顯示原始提示詞", + "status": "ready", + "required_rule": "prompt_summary_only", + "failure_if_missing": "報告 payload 可能外露原始提示詞或不可公開上下文。", + "display_allowed": false, + "evidence_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + }, + { + "check_id": "no_private_reasoning", + "display_name": "不顯示私密推理", + "status": "ready", + "required_rule": "public_reason_summary_only", + "failure_if_missing": "報告 payload 可能外露私密推理或推理鏈。", + "display_allowed": false, + "evidence_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + { + "check_id": "no_secret_values", + "display_name": "不顯示 secret / token", + "status": "ready", + "required_rule": "secret_free_payload", + "failure_if_missing": "報告 payload 可能外露機密值、權杖、授權標頭或連線字串。", + "display_allowed": false, + "evidence_hash": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + { + "check_id": "no_raw_telegram_payload", + "display_name": "不顯示原始 Telegram payload", + "status": "ready", + "required_rule": "telegram_payload_summary_only", + "failure_if_missing": "前端或 LOGBOOK 可能外露原始 Telegram payload。", + "display_allowed": false, + "evidence_hash": "sha256:8888888888888888888888888888888888888888888888888888888888888888" + }, + { + "check_id": "no_internal_collaboration_content", + "display_name": "不顯示內部協作內容", + "status": "ready", + "required_rule": "public_operator_summary_only", + "failure_if_missing": "報告可能混入內部協作逐字內容,而不是可公開的操作摘要。", + "display_allowed": false, + "evidence_hash": "sha256:9999999999999999999999999999999999999999999999999999999999999999" + } + ], + "dry_run_delivery_receipts": [ + { + "receipt_id": "daily_digest_no_send_receipt", + "display_name": "日報 no-send receipt", + "cadence": "daily", + "status": "ready_for_owner_review", + "required_fields": [ + "packet_id", + "route_id", + "dedupe_fingerprint", + "redaction_check_ids" + ], + "live_send_count": 0, + "receipt_write_allowed": false, + "evidence_hash": "sha256:abababababababababababababababababababababababababababababababab" + }, + { + "receipt_id": "weekly_digest_no_send_receipt", + "display_name": "週報 no-send receipt", + "cadence": "weekly", + "status": "ready_for_owner_review", + "required_fields": [ + "packet_id", + "zero_signal_reason", + "actionability_score", + "owner_summary" + ], + "live_send_count": 0, + "receipt_write_allowed": false, + "evidence_hash": "sha256:bcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbc" + }, + { + "receipt_id": "monthly_digest_no_send_receipt", + "display_name": "月報 no-send receipt", + "cadence": "monthly", + "status": "ready_for_owner_review", + "required_fields": [ + "packet_id", + "cost_summary", + "automation_gap_summary", + "strategic_findings" + ], + "live_send_count": 0, + "receipt_write_allowed": false, + "evidence_hash": "sha256:cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + }, + { + "receipt_id": "failure_only_no_send_receipt", + "display_name": "失敗限定 no-send receipt", + "cadence": "failure_only", + "status": "blocked_by_policy", + "required_fields": [ + "failure_signal_type", + "blocked_reason", + "next_manual_action", + "owner_agent" + ], + "live_send_count": 0, + "receipt_write_allowed": false, + "evidence_hash": "sha256:dededededededededededededededededededededededededededededededede" + } + ], + "operator_actions": [ + { + "action_id": "review_delivery_packet", + "action_type": "review_delivery_packet", + "display_name": "審查報告實發批准包", + "owner_agent": "openclaw", + "operator_instruction": "先確認日報、週報、月報與失敗限定摘要是否各自有 route、dedupe、redaction 與 owner decision。", + "live_send_allowed": false + }, + { + "action_id": "validate_sre_route", + "action_type": "validate_sre_route", + "display_name": "核對 AwoooI SRE 戰情室 route", + "owner_agent": "hermes", + "operator_instruction": "確認所有報告與失敗摘要只指向 AwoooI SRE 戰情室,舊 Bot / 舊群組維持 suppression。", + "live_send_allowed": false + }, + { + "action_id": "validate_payload_redaction", + "action_type": "validate_payload_redaction", + "display_name": "確認 payload 已遮蔽", + "owner_agent": "hermes", + "operator_instruction": "確認報告 payload 不含提示詞、私密推理、secret、原始 Telegram payload 或內部協作逐字內容。", + "live_send_allowed": false + }, + { + "action_id": "validate_zero_send_counters", + "action_type": "validate_zero_send_counters", + "display_name": "確認 send / queue / receipt 計數為 0", + "owner_agent": "nemotron", + "operator_instruction": "scheduler、Gateway queue、Telegram send、Bot API、report receipt、AI analysis 與 production write 必須保持 0。", + "live_send_allowed": false + }, + { + "action_id": "reject_or_promote", + "action_type": "reject_or_promote", + "display_name": "退回或推進 P2-112", + "owner_agent": "openclaw", + "operator_instruction": "若 route、redaction 或 zero-send counter 缺一項,維持 blocked;全部合格才進入 fixture-only runtime readback approval。", + "live_send_allowed": false + } + ], + "display_redaction_contract": { + "redaction_required": true, + "frontend_display_policy": "前端只顯示報告實發批准包、路由鎖、遮蔽規則、no-send receipt 與人工下一步;不得顯示原始提示詞、私密推理、機密值、授權標頭、原始 Telegram payload 或內部協作逐字內容。", + "raw_prompt_display_allowed": false, + "private_reasoning_display_allowed": false, + "secret_value_display_allowed": false, + "raw_telegram_payload_display_allowed": false, + "internal_collaboration_content_display_allowed": false + }, + "rollups": { + "delivery_approval_packet_count": 5, + "route_lock_gate_count": 4, + "payload_redaction_check_count": 5, + "dry_run_delivery_receipt_count": 4, + "operator_action_count": 5, + "approval_required_packet_count": 3, + "blocked_packet_count": 1, + "blocked_route_gate_count": 1, + "blocked_receipt_count": 1, + "owner_approval_received_count": 0, + "scheduled_delivery_count": 0, + "gateway_queue_write_count": 0, + "telegram_send_count": 0, + "bot_api_call_count": 0, + "report_receipt_write_count": 0, + "ai_analysis_run_count": 0, + "auto_optimization_count": 0, + "production_write_count": 0, + "secret_read_count": 0, + "destructive_operation_count": 0 + } +} diff --git a/docs/schemas/ai_agent_report_live_delivery_approval_package_v1.schema.json b/docs/schemas/ai_agent_report_live_delivery_approval_package_v1.schema.json new file mode 100644 index 00000000..cd738333 --- /dev/null +++ b/docs/schemas/ai_agent_report_live_delivery_approval_package_v1.schema.json @@ -0,0 +1,787 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://awoooi.wooo.work/schemas/ai_agent_report_live_delivery_approval_package_v1.schema.json", + "title": "AI Agent Report Live Delivery Approval Package v1", + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "generated_at", + "program_status", + "source_refs", + "prior_report_status_board", + "prior_runtime_review", + "delivery_approval_truth", + "delivery_approval_packets", + "route_lock_gates", + "payload_redaction_checks", + "dry_run_delivery_receipts", + "operator_actions", + "display_redaction_contract", + "rollups" + ], + "properties": { + "schema_version": { + "const": "ai_agent_report_live_delivery_approval_package_v1" + }, + "generated_at": { + "type": "string", + "minLength": 1 + }, + "program_status": { + "type": "object", + "additionalProperties": false, + "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": { + "const": "P2" + }, + "current_task_id": { + "const": "P2-111" + }, + "next_task_id": { + "const": "P2-112" + }, + "read_only_mode": { + "const": true + }, + "runtime_authority": { + "const": "report_live_delivery_approval_package_only_no_live_send_or_write" + }, + "status_note": { + "type": "string", + "minLength": 1 + } + } + }, + "source_refs": { + "$ref": "#/$defs/string_array" + }, + "prior_report_status_board": { + "$ref": "#/$defs/prior_report_status_board" + }, + "prior_runtime_review": { + "$ref": "#/$defs/prior_runtime_review" + }, + "delivery_approval_truth": { + "$ref": "#/$defs/delivery_approval_truth" + }, + "delivery_approval_packets": { + "type": "array", + "minItems": 5, + "items": { + "$ref": "#/$defs/delivery_approval_packet" + } + }, + "route_lock_gates": { + "type": "array", + "minItems": 4, + "items": { + "$ref": "#/$defs/route_lock_gate" + } + }, + "payload_redaction_checks": { + "type": "array", + "minItems": 5, + "items": { + "$ref": "#/$defs/payload_redaction_check" + } + }, + "dry_run_delivery_receipts": { + "type": "array", + "minItems": 4, + "items": { + "$ref": "#/$defs/dry_run_delivery_receipt" + } + }, + "operator_actions": { + "type": "array", + "minItems": 5, + "items": { + "$ref": "#/$defs/operator_action" + } + }, + "display_redaction_contract": { + "$ref": "#/$defs/display_redaction_contract" + }, + "rollups": { + "$ref": "#/$defs/rollups" + } + }, + "$defs": { + "string_array": { + "type": "array", + "minItems": 1, + "items": { + "type": "string", + "minLength": 1 + } + }, + "redacted_sha256": { + "type": "string", + "pattern": "^sha256:[0-9a-f]{64}$" + }, + "owner_agent": { + "enum": [ + "openclaw", + "hermes", + "nemotron" + ] + }, + "cadence": { + "enum": [ + "daily", + "weekly", + "monthly", + "failure_only", + "receipt" + ] + }, + "prior_report_status_board": { + "type": "object", + "additionalProperties": false, + "required": [ + "source_schema_version", + "readback_at", + "report_card_count", + "agent_status_report_count", + "visible_chart_count", + "operator_answer_count", + "work_units_total", + "work_units_done", + "work_units_waiting_approval", + "live_delivery_count", + "live_telegram_send_count_24h", + "live_auto_optimization_count_24h", + "readiness_note" + ], + "properties": { + "source_schema_version": { + "const": "ai_agent_report_status_board_v1" + }, + "readback_at": { + "type": "string", + "minLength": 1 + }, + "report_card_count": { + "const": 3 + }, + "agent_status_report_count": { + "const": 3 + }, + "visible_chart_count": { + "const": 3 + }, + "operator_answer_count": { + "const": 4 + }, + "work_units_total": { + "const": 91 + }, + "work_units_done": { + "const": 79 + }, + "work_units_waiting_approval": { + "const": 12 + }, + "live_delivery_count": { + "const": 0 + }, + "live_telegram_send_count_24h": { + "const": 0 + }, + "live_auto_optimization_count_24h": { + "const": 0 + }, + "readiness_note": { + "type": "string", + "minLength": 1 + } + } + }, + "prior_runtime_review": { + "type": "object", + "additionalProperties": false, + "required": [ + "approval_package_schema_version", + "implementation_review_schema_version", + "telegram_failure_receipt_gate_count", + "implementation_blocker_count", + "no_write_verifier_check_count", + "owner_approval_received_count", + "runtime_readback_execution_count", + "live_query_count", + "telegram_failure_receipt_send_count", + "bot_api_call_count", + "gateway_queue_write_count", + "production_write_count", + "readiness_note" + ], + "properties": { + "approval_package_schema_version": { + "const": "ai_agent_runtime_readback_approval_package_v1" + }, + "implementation_review_schema_version": { + "const": "ai_agent_runtime_readback_implementation_review_v1" + }, + "telegram_failure_receipt_gate_count": { + "const": 4 + }, + "implementation_blocker_count": { + "const": 5 + }, + "no_write_verifier_check_count": { + "const": 5 + }, + "owner_approval_received_count": { + "const": 0 + }, + "runtime_readback_execution_count": { + "const": 0 + }, + "live_query_count": { + "const": 0 + }, + "telegram_failure_receipt_send_count": { + "const": 0 + }, + "bot_api_call_count": { + "const": 0 + }, + "gateway_queue_write_count": { + "const": 0 + }, + "production_write_count": { + "const": 0 + }, + "readiness_note": { + "type": "string", + "minLength": 1 + } + } + }, + "delivery_approval_truth": { + "type": "object", + "additionalProperties": false, + "required": [ + "p2_108_report_status_loaded", + "p2_109_failure_receipt_gate_loaded", + "p2_110_implementation_review_loaded", + "delivery_approval_package_ready", + "daily_delivery_package_ready", + "weekly_delivery_package_ready", + "monthly_delivery_package_ready", + "sre_war_room_route_locked", + "payload_redaction_ready", + "dry_run_receipt_ready", + "owner_review_required_before_delivery", + "scheduler_enabled", + "gateway_queue_write_enabled", + "telegram_send_enabled", + "bot_api_call_enabled", + "report_receipt_write_enabled", + "ai_analysis_run_enabled", + "medium_low_auto_optimization_enabled", + "production_write_enabled", + "secret_read_enabled", + "destructive_operation_enabled", + "owner_approval_received_count", + "scheduled_delivery_count_24h", + "gateway_queue_write_count_24h", + "telegram_send_count_24h", + "bot_api_call_count_24h", + "report_receipt_write_count_24h", + "ai_analysis_run_count_24h", + "auto_optimization_count_24h", + "production_write_count_24h", + "secret_read_count_24h", + "destructive_operation_count_24h", + "truth_note" + ], + "properties": { + "p2_108_report_status_loaded": { + "const": true + }, + "p2_109_failure_receipt_gate_loaded": { + "const": true + }, + "p2_110_implementation_review_loaded": { + "const": true + }, + "delivery_approval_package_ready": { + "const": true + }, + "daily_delivery_package_ready": { + "const": true + }, + "weekly_delivery_package_ready": { + "const": true + }, + "monthly_delivery_package_ready": { + "const": true + }, + "sre_war_room_route_locked": { + "const": true + }, + "payload_redaction_ready": { + "const": true + }, + "dry_run_receipt_ready": { + "const": true + }, + "owner_review_required_before_delivery": { + "const": true + }, + "scheduler_enabled": { + "const": false + }, + "gateway_queue_write_enabled": { + "const": false + }, + "telegram_send_enabled": { + "const": false + }, + "bot_api_call_enabled": { + "const": false + }, + "report_receipt_write_enabled": { + "const": false + }, + "ai_analysis_run_enabled": { + "const": false + }, + "medium_low_auto_optimization_enabled": { + "const": false + }, + "production_write_enabled": { + "const": false + }, + "secret_read_enabled": { + "const": false + }, + "destructive_operation_enabled": { + "const": false + }, + "owner_approval_received_count": { + "const": 0 + }, + "scheduled_delivery_count_24h": { + "const": 0 + }, + "gateway_queue_write_count_24h": { + "const": 0 + }, + "telegram_send_count_24h": { + "const": 0 + }, + "bot_api_call_count_24h": { + "const": 0 + }, + "report_receipt_write_count_24h": { + "const": 0 + }, + "ai_analysis_run_count_24h": { + "const": 0 + }, + "auto_optimization_count_24h": { + "const": 0 + }, + "production_write_count_24h": { + "const": 0 + }, + "secret_read_count_24h": { + "const": 0 + }, + "destructive_operation_count_24h": { + "const": 0 + }, + "truth_note": { + "type": "string", + "minLength": 1 + } + } + }, + "delivery_approval_packet": { + "type": "object", + "additionalProperties": false, + "required": [ + "packet_id", + "display_name", + "cadence", + "owner_agent", + "status", + "risk_tier", + "required_approval_fields", + "blocked_runtime_actions", + "operator_guidance", + "approval_required", + "no_send_mode", + "evidence_hash" + ], + "properties": { + "packet_id": { + "type": "string", + "minLength": 1 + }, + "display_name": { + "type": "string", + "minLength": 1 + }, + "cadence": { + "$ref": "#/$defs/cadence" + }, + "owner_agent": { + "$ref": "#/$defs/owner_agent" + }, + "status": { + "enum": [ + "approval_required", + "ready_for_owner_review", + "blocked_by_policy" + ] + }, + "risk_tier": { + "enum": [ + "medium", + "high", + "critical" + ] + }, + "required_approval_fields": { + "$ref": "#/$defs/string_array" + }, + "blocked_runtime_actions": { + "$ref": "#/$defs/string_array" + }, + "operator_guidance": { + "type": "string", + "minLength": 1 + }, + "approval_required": { + "const": true + }, + "no_send_mode": { + "const": true + }, + "evidence_hash": { + "$ref": "#/$defs/redacted_sha256" + } + } + }, + "route_lock_gate": { + "type": "object", + "additionalProperties": false, + "required": [ + "gate_id", + "display_name", + "status", + "required_evidence", + "blocked_routes", + "telegram_send_enabled", + "bot_api_call_enabled", + "gateway_queue_write_enabled", + "evidence_hash" + ], + "properties": { + "gate_id": { + "type": "string", + "minLength": 1 + }, + "display_name": { + "type": "string", + "minLength": 1 + }, + "status": { + "enum": [ + "ready_for_owner_review", + "approval_required", + "blocked_by_policy" + ] + }, + "required_evidence": { + "$ref": "#/$defs/string_array" + }, + "blocked_routes": { + "$ref": "#/$defs/string_array" + }, + "telegram_send_enabled": { + "const": false + }, + "bot_api_call_enabled": { + "const": false + }, + "gateway_queue_write_enabled": { + "const": false + }, + "evidence_hash": { + "$ref": "#/$defs/redacted_sha256" + } + } + }, + "payload_redaction_check": { + "type": "object", + "additionalProperties": false, + "required": [ + "check_id", + "display_name", + "status", + "required_rule", + "failure_if_missing", + "display_allowed", + "evidence_hash" + ], + "properties": { + "check_id": { + "type": "string", + "minLength": 1 + }, + "display_name": { + "type": "string", + "minLength": 1 + }, + "status": { + "enum": [ + "ready", + "blocked_by_policy" + ] + }, + "required_rule": { + "type": "string", + "minLength": 1 + }, + "failure_if_missing": { + "type": "string", + "minLength": 1 + }, + "display_allowed": { + "const": false + }, + "evidence_hash": { + "$ref": "#/$defs/redacted_sha256" + } + } + }, + "dry_run_delivery_receipt": { + "type": "object", + "additionalProperties": false, + "required": [ + "receipt_id", + "display_name", + "cadence", + "status", + "required_fields", + "live_send_count", + "receipt_write_allowed", + "evidence_hash" + ], + "properties": { + "receipt_id": { + "type": "string", + "minLength": 1 + }, + "display_name": { + "type": "string", + "minLength": 1 + }, + "cadence": { + "$ref": "#/$defs/cadence" + }, + "status": { + "enum": [ + "ready_for_owner_review", + "blocked_by_policy" + ] + }, + "required_fields": { + "$ref": "#/$defs/string_array" + }, + "live_send_count": { + "const": 0 + }, + "receipt_write_allowed": { + "const": false + }, + "evidence_hash": { + "$ref": "#/$defs/redacted_sha256" + } + } + }, + "operator_action": { + "type": "object", + "additionalProperties": false, + "required": [ + "action_id", + "action_type", + "display_name", + "owner_agent", + "operator_instruction", + "live_send_allowed" + ], + "properties": { + "action_id": { + "type": "string", + "minLength": 1 + }, + "action_type": { + "enum": [ + "review_delivery_packet", + "validate_sre_route", + "validate_payload_redaction", + "validate_zero_send_counters", + "reject_or_promote" + ] + }, + "display_name": { + "type": "string", + "minLength": 1 + }, + "owner_agent": { + "$ref": "#/$defs/owner_agent" + }, + "operator_instruction": { + "type": "string", + "minLength": 1 + }, + "live_send_allowed": { + "const": false + } + } + }, + "display_redaction_contract": { + "type": "object", + "additionalProperties": false, + "required": [ + "redaction_required", + "frontend_display_policy", + "raw_prompt_display_allowed", + "private_reasoning_display_allowed", + "secret_value_display_allowed", + "raw_telegram_payload_display_allowed", + "internal_collaboration_content_display_allowed" + ], + "properties": { + "redaction_required": { + "const": true + }, + "frontend_display_policy": { + "type": "string", + "minLength": 1 + }, + "raw_prompt_display_allowed": { + "const": false + }, + "private_reasoning_display_allowed": { + "const": false + }, + "secret_value_display_allowed": { + "const": false + }, + "raw_telegram_payload_display_allowed": { + "const": false + }, + "internal_collaboration_content_display_allowed": { + "const": false + } + } + }, + "rollups": { + "type": "object", + "additionalProperties": false, + "required": [ + "delivery_approval_packet_count", + "route_lock_gate_count", + "payload_redaction_check_count", + "dry_run_delivery_receipt_count", + "operator_action_count", + "approval_required_packet_count", + "blocked_packet_count", + "blocked_route_gate_count", + "blocked_receipt_count", + "owner_approval_received_count", + "scheduled_delivery_count", + "gateway_queue_write_count", + "telegram_send_count", + "bot_api_call_count", + "report_receipt_write_count", + "ai_analysis_run_count", + "auto_optimization_count", + "production_write_count", + "secret_read_count", + "destructive_operation_count" + ], + "properties": { + "delivery_approval_packet_count": { + "const": 5 + }, + "route_lock_gate_count": { + "const": 4 + }, + "payload_redaction_check_count": { + "const": 5 + }, + "dry_run_delivery_receipt_count": { + "const": 4 + }, + "operator_action_count": { + "const": 5 + }, + "approval_required_packet_count": { + "const": 3 + }, + "blocked_packet_count": { + "const": 1 + }, + "blocked_route_gate_count": { + "const": 1 + }, + "blocked_receipt_count": { + "const": 1 + }, + "owner_approval_received_count": { + "const": 0 + }, + "scheduled_delivery_count": { + "const": 0 + }, + "gateway_queue_write_count": { + "const": 0 + }, + "telegram_send_count": { + "const": 0 + }, + "bot_api_call_count": { + "const": 0 + }, + "report_receipt_write_count": { + "const": 0 + }, + "ai_analysis_run_count": { + "const": 0 + }, + "auto_optimization_count": { + "const": 0 + }, + "production_write_count": { + "const": 0 + }, + "secret_read_count": { + "const": 0 + }, + "destructive_operation_count": { + "const": 0 + } + } + } + } +} 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 8adc8e44..4aaddeab 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 @@ -648,6 +648,7 @@ Alert / Sentry / SigNoz / Gitea / Market Watch / Operator | `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_runtime_readback_approval_package_2026-06-13.json` + `GET /api/v1/agents/agent-runtime-readback-approval-package` | P2-109 runtime readback approval package;承接 P2-107 readback / promotion readiness 與 P2-108 report status board,建立 5 個批准包、4 個 canonical readback plan、4 條 rollback drill、4 個 Telegram failure receipt gate 與 5 個 operator action;canonical runtime readback、runtime readback execution、owner approval received、reviewer queue write、rollback work item write、Gateway queue、Telegram failure receipt、Bot API、score / result capture / learning / trust / production write、secret read 與 destructive action 全部 `0 / false`,下一步 P2-110 | | `docs/evaluations/ai_agent_runtime_readback_implementation_review_2026-06-13.json` + `GET /api/v1/agents/agent-runtime-readback-implementation-review` | P2-110 runtime readback implementation review;承接 P2-109 approval package,建立 5 張 implementation review card、5 個 no-write verifier check、5 個 implementation blocker 與 5 個 operator action;canonical runtime readback、live query、runtime readback execution、owner approval received、reviewer queue write、rollback work item write、Gateway queue、Telegram failure receipt、Bot API、score / result capture / learning / trust / production write、secret read 與 destructive action 全部 `0 / false`,下一步 P2-111 | +| `docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json` + `GET /api/v1/agents/agent-report-live-delivery-approval-package` | P2-111 report live delivery approval package;承接 P2-108 report status board、P2-109 Telegram failure receipt gate 與 P2-110 implementation review,建立日報 / 週報 / 月報 / 失敗限定摘要 / 讀報回執 5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt 與 5 個 operator action;scheduler、Gateway queue、Telegram send、Bot API、report receipt write、AI analysis run、中低風險 auto optimization、production write、secret read 與 destructive action 全部 `0 / false`,下一步 P2-112 | | `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 主動營運委派與版本生命週期契約 @@ -747,6 +748,7 @@ Repo / registry / release notes / K8s / host / observability / backup evidence 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。 30. 建立 runtime readback approval package。✅ P2-109 已完成;批准包 `5`、canonical readback plan `4`、rollback drill `4`、Telegram failure receipt gate `4`、operator action `5`,canonical runtime readback、runtime readback execution、owner approval received、reviewer queue write、rollback work item write、Gateway / Telegram failure receipt / Bot API / production write 仍為 `0 / false`。下一步 P2-110。 31. 建立 runtime readback implementation review。✅ P2-110 已完成並正式驗證;implementation review card `5`、no-write verifier check `5`、implementation blocker `5`、operator action `5`,approval required card `2`、critical blocker `2`;canonical runtime readback、live query、runtime readback execution、owner approval received、reviewer queue write、rollback work item write、Gateway / Telegram failure receipt / Bot API / production write 仍為 `0 / false`。下一步 P2-111。 +32. 建立 report live delivery approval package。✅ P2-111 已本地完成;delivery approval packet `5`、route lock gate `4`、payload redaction check `5`、no-send receipt `4`、operator action `5`,approval required packet `3`、blocked total `3`;scheduler、Gateway queue write、Telegram send、Bot API、report receipt write、AI analysis run、中低風險 auto optimization、production write 仍為 `0 / false`。下一步 P2-112。 #### 3.2.1d 2026-06-11 Agent 互動、學習與成長證據面 @@ -791,6 +793,8 @@ Repo / registry / release notes / K8s / host / observability / backup evidence | `docs/evaluations/ai_agent_runtime_readback_approval_package_2026-06-13.json` + `GET /api/v1/agents/agent-runtime-readback-approval-package` | P2-109 committed snapshot;5 個批准包、4 個 canonical readback plan、4 條 rollback drill、4 個 Telegram failure receipt gate、5 個 operator action;不讀 canonical runtime target、不寫 reviewer queue、不寫 rollback work item、不送 Telegram、不呼叫 Bot API、不寫 production target、不讀 secret、不執行 destructive action | | `docs/schemas/ai_agent_runtime_readback_implementation_review_v1.schema.json` | P2-110 runtime readback implementation review schema;強制 canonical runtime readback、live query、runtime readback execution、owner approval received、reviewer queue write、rollback work item write、Gateway queue、Telegram failure receipt、Bot API、score write、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部維持 `0 / false` | | `docs/evaluations/ai_agent_runtime_readback_implementation_review_2026-06-13.json` + `GET /api/v1/agents/agent-runtime-readback-implementation-review` | P2-110 committed snapshot;5 張 implementation review card、5 個 no-write verifier check、5 個 implementation blocker、5 個 operator action;不讀 canonical runtime target、不做 live query、不寫 reviewer queue、不寫 rollback work item、不送 Telegram、不呼叫 Bot API、不寫 production target、不讀 secret、不執行 destructive action | +| `docs/schemas/ai_agent_report_live_delivery_approval_package_v1.schema.json` | P2-111 report live delivery approval package schema;強制 scheduler、Gateway queue write、Telegram send、Bot API、report receipt write、AI analysis run、中低風險 auto optimization、production write、secret read 與 destructive action 全部維持 `0 / false` | +| `docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json` + `GET /api/v1/agents/agent-report-live-delivery-approval-package` | P2-111 committed snapshot;5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt、5 個 operator action;不排程、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不啟動 AI analysis、不做自動優化、不寫 production target、不讀 secret、不執行 destructive action | | `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 仍需批准 | @@ -1995,6 +1999,14 @@ Phase 6 完成後 - 政策裁決:P2-109 只允許 owner review 批准包、canonical readback plan、rollback drill 與 failure receipt gate 可視化;不得把批准包或 gate 解讀成 canonical runtime readback、reviewer queue write、Telegram 實發、Bot API 呼叫、rollback work item write 或 live writer 已啟用。 - 本波仍不讀 canonical runtime target、不寫 score、不寫 result capture、不寫 learning、不更新 PlayBook trust、不寫 KM、不 runtime append LOGBOOK、不寫 audit DB、不寫 timeline、不寫 reviewer queue、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 rollback work item、不啟動 runtime worker、不讀 secret、不執行 destructive action、不回傳內部協作內容;下一步 P2-110。 +### 2026-06-13 17:18 (台北) — §3.2 / §5 — 本地完成 P2-111 report live delivery approval package — 把日週月報與失敗摘要轉成實發批准面 + +- 新增 `ai_agent_report_live_delivery_approval_package_v1` schema / committed snapshot / loader / API / 測試,承接 P2-108 report status board、P2-109 Telegram failure receipt gate 與 P2-110 implementation review,定義 5 個 report delivery approval packet、4 個 route lock gate、5 個 payload redaction check、4 個 no-send delivery receipt 與 5 個 operator action。 +- `apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx` 接入 `GET /api/v1/agents/agent-report-live-delivery-approval-package`,治理頁顯示 P2-111 進度 `100%`、批准包 `5`、route gate `4`、遮蔽檢查 `5`、no-send receipt `4`、操作選項 `5`、需批准 `3`、阻擋總數 `3`、owner approval received `0`、scheduler `0`、Gateway queue `0`、Telegram send `0`、Bot API `0`、report receipt write `0`、AI analysis `0`、auto optimization `0` 與 live writes `0`。 +- 本地驗證:P2-108 / P2-109 / P2-110 / P2-111 API/service regression `37 passed`、JSON parse、py_compile、i18n mirror `10884` leaves diff `0`、web typecheck、source-control owner response guard、security mirror progress guard 與 `git diff --check` 通過。 +- 政策裁決:P2-111 只允許 committed approval package、route lock、redaction check、no-send receipt 與 operator action 可視化;不得把批准包、route lock 或 no-send receipt 解讀成 scheduler、Gateway queue、Telegram 實發、Bot API、report receipt write、AI analysis runtime、中低風險 auto optimization 或 production write 已啟用。 +- 本波仍不排程、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不啟動 AI analysis、不啟動中低風險 auto worker、不寫 production target、不讀 secret、不執行 destructive action、不回傳內部協作內容;下一步 P2-112。 + ### 2026-06-13 16:26 (台北) — §3.2 / §5 — 完成 P2-110 runtime readback implementation review — 把批准包轉成實作審查面 - 新增 `ai_agent_runtime_readback_implementation_review_v1` schema / committed snapshot / loader / API / 測試,承接 P2-109 的批准包、canonical readback plan、rollback drill 與 Telegram failure receipt gate,定義 5 張 implementation review card、5 個 no-write verifier check、5 個 implementation blocker 與 5 個 operator action。