From f737f278dc14372ff1fb15b124b1370c20e1bb99 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 14 Jun 2026 10:17:17 +0800 Subject: [PATCH] =?UTF-8?q?feat(governance):=20=E6=96=B0=E5=A2=9E=20releas?= =?UTF-8?q?e=20verifier=20owner=20review=20packet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api/src/api/v1/agents.py | 35 ++ ...re_release_verifier_owner_review_packet.py | 392 +++++++++++++ ...re_release_verifier_owner_review_packet.py | 129 ++++ ...elease_verifier_owner_review_packet_api.py | 33 ++ apps/web/messages/en.json | 36 ++ apps/web/messages/zh-TW.json | 36 ++ .../tabs/automation-inventory-tab.tsx | 191 +++++- apps/web/src/lib/api-client.ts | 248 ++++++++ docs/LOGBOOK.md | 23 + ...AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md | 15 +- ...rifier_owner_review_packet_2026-06-14.json | 554 ++++++++++++++++++ ...erifier_owner_review_packet_v1.schema.json | 109 ++++ ...-04-15-MASTER-ai-autonomous-flywheel-v2.md | 11 +- 13 files changed, 1807 insertions(+), 5 deletions(-) create mode 100644 apps/api/src/services/ai_agent_result_capture_release_verifier_owner_review_packet.py create mode 100644 apps/api/tests/test_ai_agent_result_capture_release_verifier_owner_review_packet.py create mode 100644 apps/api/tests/test_ai_agent_result_capture_release_verifier_owner_review_packet_api.py create mode 100644 docs/evaluations/ai_agent_result_capture_release_verifier_owner_review_packet_2026-06-14.json create mode 100644 docs/schemas/ai_agent_result_capture_release_verifier_owner_review_packet_v1.schema.json diff --git a/apps/api/src/api/v1/agents.py b/apps/api/src/api/v1/agents.py index 6296c24ea..c169d7617 100644 --- a/apps/api/src/api/v1/agents.py +++ b/apps/api/src/api/v1/agents.py @@ -154,6 +154,9 @@ from src.services.ai_agent_result_capture_release_authorization_readback_gate im from src.services.ai_agent_result_capture_release_verifier_preflight_gate import ( load_latest_ai_agent_result_capture_release_verifier_preflight_gate, ) +from src.services.ai_agent_result_capture_release_verifier_owner_review_packet import ( + load_latest_ai_agent_result_capture_release_verifier_owner_review_packet, +) from src.services.ai_agent_result_capture_post_release_verifier_rollback_gate import ( load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate, ) @@ -2221,6 +2224,38 @@ async def get_agent_result_capture_release_verifier_preflight_gate() -> dict[str ) from exc +@router.get( + "/agent-result-capture-release-verifier-owner-review-packet", + response_model=dict[str, Any], + summary="取得 AI Agent result capture release verifier owner review packet", + description=( + "讀取最新已提交的 P2-137 release verifier owner review packet;" + "此端點只回傳 owner review packet、verifier review packet、rollback owner review、maintenance window review hold、" + "live apply owner review hold、blocked owner review transition 與 operator action," + "不授權 owner release、不批准維護窗口、不確認 rollback owner、不通過 post-release verifier、" + "不核發或通過 release authorization、不釋放 rollback release 或 live apply、不套用 writer、" + "不寫 receipt、result capture、learning、PlayBook trust、reviewer queue 或 Gateway queue," + "不送 Telegram、不呼叫 Bot API、不讀 secret、不執行 production 寫入。" + ), +) +async def get_agent_result_capture_release_verifier_owner_review_packet() -> dict[str, Any]: + """Return the latest read-only release verifier owner review packet.""" + try: + payload = await asyncio.to_thread(load_latest_ai_agent_result_capture_release_verifier_owner_review_packet) + 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_result_capture_release_verifier_owner_review_packet_invalid", error=str(exc)) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="AI Agent result capture release verifier owner review packet 無效", + ) from exc + + @router.get( "/agent-owner-approved-fixture-dry-run", response_model=dict[str, Any], diff --git a/apps/api/src/services/ai_agent_result_capture_release_verifier_owner_review_packet.py b/apps/api/src/services/ai_agent_result_capture_release_verifier_owner_review_packet.py new file mode 100644 index 000000000..59648d6b8 --- /dev/null +++ b/apps/api/src/services/ai_agent_result_capture_release_verifier_owner_review_packet.py @@ -0,0 +1,392 @@ +""" +AI Agent result capture release verifier owner review packet snapshot. + +Loads the latest committed P2-137 owner review packet. This module validates +committed evidence only; it never authorizes owner release, approves +maintenance windows, confirms rollback owners, passes release authorization, +releases live apply, applies writers, writes receipts, writes result captures, +writes learning records, updates PlayBook trust, writes reviewer / Gateway +queues, sends Telegram messages, reads secrets, or performs destructive +operations. +""" + +from __future__ import annotations + +import json +import re +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_result_capture_release_verifier_owner_review_packet_*.json" +_SCHEMA_VERSION = "ai_agent_result_capture_release_verifier_owner_review_packet_v1" +_RUNTIME_AUTHORITY = "result_capture_release_verifier_owner_review_packet_only_no_live_write" + + +def load_latest_ai_agent_result_capture_release_verifier_owner_review_packet( + evaluations_dir: Path | None = None, +) -> dict[str, Any]: + """Load the newest committed release verifier owner review packet.""" + directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR + candidates = sorted(directory.glob(_SNAPSHOT_PATTERN)) + if not candidates: + raise FileNotFoundError(f"no AI Agent result capture release verifier owner review packet 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") + + label = str(latest) + _require_schema(payload, label) + _require_prior(payload, label) + _require_truth(payload, label) + _require_owner_review_packets(payload, label) + _require_verifier_packets(payload, label) + _require_rollback_owner_packets(payload, label) + _require_maintenance_holds(payload, label) + _require_live_apply_holds(payload, label) + _require_blocked_transitions(payload, label) + _require_actions(payload, label) + _require_display_redaction(payload, label) + _require_no_forbidden_display_terms(payload, label) + _require_rollup_consistency(payload, label) + 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 {} + expected = { + "current_priority": "P2", + "current_task_id": "P2-137", + "next_task_id": "P2-138", + "read_only_mode": True, + "runtime_authority": _RUNTIME_AUTHORITY, + "overall_completion_percent": 100, + } + mismatches = _mismatches(status, expected) + if mismatches: + raise ValueError(f"{label}: program_status mismatch: {mismatches}") + if not status.get("status_note"): + raise ValueError(f"{label}: program_status.status_note is required") + + +def _require_prior(payload: dict[str, Any], label: str) -> None: + prior = payload.get("prior_release_verifier_preflight_gate") or {} + expected = { + "schema_version": "ai_agent_result_capture_release_verifier_preflight_gate_v1", + "release_verifier_preflight_count": 5, + "rollback_verifier_preflight_count": 5, + "maintenance_window_verifier_hold_count": 5, + "live_apply_verifier_hold_count": 5, + "blocked_verifier_preflight_transition_count": 6, + "operator_action_count": 5, + "approval_required_total": 8, + "blocked_total": 9, + } + expected.update(_zero_count_expectations(include_owner_review=True)) + mismatches = _mismatches(prior, expected) + if mismatches: + raise ValueError(f"{label}: prior_release_verifier_preflight_gate mismatch: {mismatches}") + if not prior.get("readiness_note"): + raise ValueError(f"{label}: prior_release_verifier_preflight_gate.readiness_note is required") + + +def _require_truth(payload: dict[str, Any], label: str) -> None: + truth = payload.get("release_verifier_owner_review_truth") or {} + required_true = { + "p2_136_release_verifier_preflight_gate_loaded", + "owner_review_packet_ready", + "release_verifier_review_required", + "rollback_owner_review_required", + "maintenance_window_review_required", + "live_apply_review_required", + "redaction_review_required", + "owner_review_packet_only", + } + missing = sorted(field for field in required_true if truth.get(field) is not True) + if missing: + raise ValueError(f"{label}: owner review packet flags must remain true: {missing}") + + required_false = { + "owner_release_authorized", + "owner_release_approved", + "owner_review_approved", + "maintenance_window_approved", + "rollback_owner_confirmed", + "post_release_verifier_ready", + "final_release_candidate_approved", + "final_release_candidate_passed", + "release_authorization_granted", + "release_authorization_passed", + "rollback_release_passed", + "live_apply_release_passed", + "writer_apply_enabled", + "execution_apply_enabled", + "receipt_write_enabled", + "reviewer_queue_write_enabled", + "gateway_queue_write_enabled", + "telegram_send_enabled", + "bot_api_call_enabled", + "report_receipt_write_enabled", + "result_capture_write_enabled", + "learning_write_enabled", + "playbook_trust_write_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}: owner review packet live/send/write flags must remain false: {unsafe}") + + non_zero = sorted(field for field in _zero_count_expectations(include_owner_review=True) if truth.get(field) != 0) + if non_zero: + raise ValueError(f"{label}: owner review packet live counters must remain zero: {non_zero}") + if not truth.get("truth_note"): + raise ValueError(f"{label}: release_verifier_owner_review_truth.truth_note is required") + + +def _require_owner_review_packets(payload: dict[str, Any], label: str) -> None: + items = payload.get("owner_review_packets") or [] + _require_ids( + items, + "packet_id", + { + "owner_review_packet_result_capture", + "owner_review_packet_learning", + "owner_review_packet_playbook_trust", + "owner_review_packet_reviewer_queue", + "owner_review_packet_gateway_queue", + }, + label, + "owner review packets", + ) + for item in items: + item_id = item.get("packet_id") + if item.get("packet_mode") != "release_verifier_owner_review_packet": + raise ValueError(f"{label}: owner review packet {item_id} mode is invalid") + if item.get("owner_release_authorized") is not False or item.get("owner_review_approved") is not False: + raise ValueError(f"{label}: owner review packet {item_id} must stay unauthorized and unapproved") + if item.get("release_authorization_granted") is not False or item.get("release_authorization_passed") is not False: + raise ValueError(f"{label}: owner review packet {item_id} must stay ungranted and unpassed") + _require_valid_status(item, label, f"owner review packet {item_id}") + if not item.get("review_summary") or not _is_redacted_sha256(item.get("evidence_hash")): + raise ValueError(f"{label}: owner review packet {item_id} must include review_summary and redacted evidence_hash") + + +def _require_verifier_packets(payload: dict[str, Any], label: str) -> None: + items = payload.get("verifier_review_packets") or [] + _require_count(items, 5, label, "verifier review packets") + for item in items: + item_id = item.get("packet_id") + if item.get("packet_mode") != "release_verifier_review_packet": + raise ValueError(f"{label}: verifier review packet {item_id} mode is invalid") + if item.get("post_release_verifier_required") is not True: + raise ValueError(f"{label}: verifier review packet {item_id} must require post-release verifier") + if item.get("post_release_verifier_ready") is not False or item.get("release_authorization_passed") is not False: + raise ValueError(f"{label}: verifier review packet {item_id} must stay unready and unpassed") + _require_valid_status(item, label, f"verifier review packet {item_id}") + + +def _require_rollback_owner_packets(payload: dict[str, Any], label: str) -> None: + items = payload.get("rollback_owner_review_packets") or [] + _require_count(items, 5, label, "rollback owner review packets") + for item in items: + item_id = item.get("packet_id") + if item.get("packet_mode") != "rollback_owner_review_packet": + raise ValueError(f"{label}: rollback owner review packet {item_id} mode is invalid") + if item.get("rollback_owner_required") is not True: + raise ValueError(f"{label}: rollback owner review packet {item_id} must require rollback owner") + if item.get("rollback_owner_confirmed") is not False or item.get("rollback_release_passed") is not False: + raise ValueError(f"{label}: rollback owner review packet {item_id} must stay unconfirmed and unpassed") + _require_valid_status(item, label, f"rollback owner review packet {item_id}") + + +def _require_maintenance_holds(payload: dict[str, Any], label: str) -> None: + items = payload.get("maintenance_window_review_holds") or [] + _require_count(items, 5, label, "maintenance window review holds") + for item in items: + item_id = item.get("hold_id") + if item.get("hold_mode") != "maintenance_window_owner_review_hold": + raise ValueError(f"{label}: maintenance window review hold {item_id} mode is invalid") + if item.get("maintenance_window_required") is not True: + raise ValueError(f"{label}: maintenance window review hold {item_id} must require maintenance window") + if item.get("owner_release_authorized") is not False or item.get("maintenance_window_approved") is not False: + raise ValueError(f"{label}: maintenance window review hold {item_id} must keep owner release and maintenance unapproved") + _require_valid_status(item, label, f"maintenance window review hold {item_id}") + + +def _require_live_apply_holds(payload: dict[str, Any], label: str) -> None: + items = payload.get("live_apply_owner_review_holds") or [] + _require_count(items, 5, label, "live apply owner review holds") + for item in items: + item_id = item.get("hold_id") + if item.get("hold_mode") != "live_apply_owner_review_hold": + raise ValueError(f"{label}: live apply owner review hold {item_id} mode is invalid") + if ( + item.get("release_authorization_granted") is not False + or item.get("release_authorization_passed") is not False + or item.get("live_apply_release_passed") is not False + or item.get("live_apply_release_enabled") is not False + ): + raise ValueError(f"{label}: live apply owner review hold {item_id} must stay ungranted, unpassed, and disabled") + _require_valid_status(item, label, f"live apply owner review hold {item_id}") + + +def _require_blocked_transitions(payload: dict[str, Any], label: str) -> None: + items = payload.get("blocked_owner_review_transitions") or [] + _require_count(items, 6, label, "blocked owner review transitions") + for item in items: + item_id = item.get("transition_id") + if item.get("runtime_write_allowed") is not False: + raise ValueError(f"{label}: blocked owner review transition {item_id} must keep runtime_write_allowed=false") + if item.get("status") not in {"blocked_by_policy", "approval_required"}: + raise ValueError(f"{label}: blocked owner review transition {item_id} status is invalid") + if not item.get("reason"): + raise ValueError(f"{label}: blocked owner review transition {item_id}.reason is required") + + +def _require_actions(payload: dict[str, Any], label: str) -> None: + items = payload.get("operator_actions") or [] + _require_count(items, 5, label, "operator actions") + for item in items: + item_id = item.get("action_id") + if item.get("runtime_write_allowed") is not False: + raise ValueError(f"{label}: operator action {item_id} must keep runtime_write_allowed=false") + if item.get("status") not in {"ready_for_operator_review", "approval_required"}: + raise ValueError(f"{label}: operator action {item_id} status is invalid") + if not item.get("operator_instruction"): + raise ValueError(f"{label}: operator action {item_id}.operator_instruction is required") + + +def _require_display_redaction(payload: dict[str, Any], label: str) -> None: + contract = payload.get("display_redaction_contract") or {} + expected = { + "redaction_required": True, + "raw_prompt_display_allowed": False, + "private_reasoning_display_allowed": False, + "secret_value_display_allowed": False, + "raw_runtime_payload_display_allowed": False, + "internal_collaboration_content_display_allowed": False, + } + mismatches = _mismatches(contract, expected) + if mismatches: + raise ValueError(f"{label}: display_redaction_contract mismatch: {mismatches}") + if not contract.get("frontend_display_policy"): + raise ValueError(f"{label}: display_redaction_contract.frontend_display_policy is required") + + +def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None: + rollups = payload.get("rollups") or {} + expected = { + "owner_review_packet_count": len(payload.get("owner_review_packets") or []), + "verifier_review_packet_count": len(payload.get("verifier_review_packets") or []), + "rollback_owner_review_packet_count": len(payload.get("rollback_owner_review_packets") or []), + "maintenance_window_review_hold_count": len(payload.get("maintenance_window_review_holds") or []), + "live_apply_owner_review_hold_count": len(payload.get("live_apply_owner_review_holds") or []), + "blocked_owner_review_transition_count": len(payload.get("blocked_owner_review_transitions") or []), + "operator_action_count": len(payload.get("operator_actions") or []), + } + expected.update(_zero_count_expectations(include_owner_review=True)) + mismatches = _mismatches(rollups, expected) + if mismatches: + raise ValueError(f"{label}: rollups mismatch: {mismatches}") + + +def _require_no_forbidden_display_terms(payload: Any, label: str) -> None: + forbidden = { + "work_window_transcript", + "internal_collaboration_transcript", + "raw_prompt", + "private_reasoning", + "chain_of_thought", + "authorization_header", + "secret_value", + } + found = sorted(term for term in forbidden if _contains_term(payload, term)) + if found: + raise ValueError(f"{label}: forbidden display terms leaked: {found}") + + +def _contains_term(value: Any, term: str) -> bool: + if isinstance(value, str): + return term.lower() in value.lower() + if isinstance(value, dict): + return any(_contains_term(child, term) for child in value.values()) + if isinstance(value, list): + return any(_contains_term(child, term) for child in value) + return False + + +def _zero_count_expectations(*, include_owner_review: bool) -> dict[str, int]: + counts = { + "owner_release_authorized_count": 0, + "owner_release_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "final_release_candidate_approved_count": 0, + "final_release_candidate_pass_count": 0, + "release_authorization_granted_count": 0, + "release_authorization_pass_count": 0, + "rollback_release_pass_count": 0, + "live_apply_release_pass_count": 0, + "writer_apply_count": 0, + "execution_apply_count": 0, + "receipt_write_count": 0, + "reviewer_queue_write_count": 0, + "gateway_queue_write_count": 0, + "telegram_send_count": 0, + "bot_api_call_count": 0, + "report_receipt_write_count": 0, + "result_capture_write_count": 0, + "learning_write_count": 0, + "playbook_trust_write_count": 0, + "production_write_count": 0, + "secret_read_count": 0, + "destructive_operation_count": 0, + } + if include_owner_review: + counts["owner_review_approved_count"] = 0 + return counts + + +def _require_ids( + items: list[dict[str, Any]], + field: str, + expected_ids: set[str], + label: str, + group_name: str, +) -> None: + actual_ids = {str(item.get(field)) for item in items} + if actual_ids != expected_ids: + raise ValueError(f"{label}: {group_name} ids mismatch: expected={sorted(expected_ids)} actual={sorted(actual_ids)}") + + +def _require_count(items: list[Any], expected: int, label: str, group_name: str) -> None: + if len(items) != expected: + raise ValueError(f"{label}: expected {expected} {group_name}, got {len(items)}") + + +def _require_valid_status(item: dict[str, Any], label: str, item_label: str) -> None: + if item.get("status") not in {"ready_for_owner_review", "approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: {item_label} status is invalid") + + +def _is_redacted_sha256(value: Any) -> bool: + return isinstance(value, str) and re.fullmatch(r"sha256:[0-9a-f]{64}", value) is not None + + +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 + } diff --git a/apps/api/tests/test_ai_agent_result_capture_release_verifier_owner_review_packet.py b/apps/api/tests/test_ai_agent_result_capture_release_verifier_owner_review_packet.py new file mode 100644 index 000000000..04077681e --- /dev/null +++ b/apps/api/tests/test_ai_agent_result_capture_release_verifier_owner_review_packet.py @@ -0,0 +1,129 @@ +from __future__ import annotations + +import copy +import json +from pathlib import Path + +import pytest + +from src.services.ai_agent_result_capture_release_verifier_owner_review_packet import ( + load_latest_ai_agent_result_capture_release_verifier_owner_review_packet, +) + + +def test_load_latest_release_verifier_owner_review_packet_snapshot() -> None: + snapshot = load_latest_ai_agent_result_capture_release_verifier_owner_review_packet() + + assert snapshot["schema_version"] == "ai_agent_result_capture_release_verifier_owner_review_packet_v1" + assert snapshot["program_status"]["current_task_id"] == "P2-137" + assert snapshot["program_status"]["next_task_id"] == "P2-138" + assert snapshot["program_status"]["overall_completion_percent"] == 100 + assert snapshot["program_status"]["runtime_authority"] == "result_capture_release_verifier_owner_review_packet_only_no_live_write" + + rollups = snapshot["rollups"] + assert rollups["owner_review_packet_count"] == 5 + assert rollups["verifier_review_packet_count"] == 5 + assert rollups["rollback_owner_review_packet_count"] == 5 + assert rollups["maintenance_window_review_hold_count"] == 5 + assert rollups["live_apply_owner_review_hold_count"] == 5 + assert rollups["blocked_owner_review_transition_count"] == 6 + assert rollups["operator_action_count"] == 5 + assert ( + rollups["approval_required_owner_review_count"] + + rollups["approval_required_verifier_review_count"] + + rollups["approval_required_rollback_owner_review_count"] + + rollups["approval_required_maintenance_window_count"] + + rollups["approval_required_live_apply_review_count"] + ) == 10 + assert ( + rollups["blocked_owner_review_count"] + + rollups["blocked_verifier_review_count"] + + rollups["blocked_rollback_owner_review_count"] + + rollups["blocked_maintenance_window_count"] + + rollups["blocked_live_apply_review_count"] + + rollups["critical_blocker_count"] + ) == 10 + + assert rollups["owner_release_authorized_count"] == 0 + assert rollups["owner_review_approved_count"] == 0 + assert rollups["release_authorization_granted_count"] == 0 + assert rollups["release_authorization_pass_count"] == 0 + assert rollups["rollback_release_pass_count"] == 0 + assert rollups["live_apply_release_pass_count"] == 0 + assert rollups["writer_apply_count"] == 0 + assert rollups["execution_apply_count"] == 0 + assert rollups["receipt_write_count"] == 0 + assert rollups["reviewer_queue_write_count"] == 0 + assert rollups["gateway_queue_write_count"] == 0 + assert rollups["telegram_send_count"] == 0 + assert rollups["bot_api_call_count"] == 0 + assert rollups["report_receipt_write_count"] == 0 + assert rollups["result_capture_write_count"] == 0 + assert rollups["learning_write_count"] == 0 + assert rollups["playbook_trust_write_count"] == 0 + assert rollups["production_write_count"] == 0 + + +def test_owner_review_packet_truth_keeps_all_live_paths_closed() -> None: + snapshot = load_latest_ai_agent_result_capture_release_verifier_owner_review_packet() + truth = snapshot["release_verifier_owner_review_truth"] + + assert truth["p2_136_release_verifier_preflight_gate_loaded"] is True + assert truth["owner_review_packet_ready"] is True + assert truth["release_verifier_review_required"] is True + assert truth["owner_release_authorized"] is False + assert truth["owner_review_approved"] is False + assert truth["maintenance_window_approved"] is False + assert truth["rollback_owner_confirmed"] is False + assert truth["post_release_verifier_ready"] is False + assert truth["release_authorization_granted"] is False + assert truth["release_authorization_passed"] is False + assert truth["rollback_release_passed"] is False + assert truth["live_apply_release_passed"] is False + assert truth["writer_apply_enabled"] is False + assert truth["gateway_queue_write_enabled"] is False + assert truth["telegram_send_enabled"] is False + assert truth["production_write_enabled"] is False + assert truth["secret_read_enabled"] is False + assert truth["destructive_operation_enabled"] is False + + +def test_rejects_owner_review_approved(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_verifier_owner_review_packet()) + snapshot["owner_review_packets"][0]["owner_review_approved"] = True + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="must stay unauthorized and unapproved"): + load_latest_ai_agent_result_capture_release_verifier_owner_review_packet(tmp_path) + + +def test_rejects_live_apply_release_enabled(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_verifier_owner_review_packet()) + snapshot["live_apply_owner_review_holds"][0]["live_apply_release_enabled"] = True + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="must stay ungranted, unpassed, and disabled"): + load_latest_ai_agent_result_capture_release_verifier_owner_review_packet(tmp_path) + + +def test_rejects_rollup_drift(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_verifier_owner_review_packet()) + snapshot["rollups"]["owner_review_packet_count"] = 4 + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="rollups mismatch"): + load_latest_ai_agent_result_capture_release_verifier_owner_review_packet(tmp_path) + + +def test_rejects_forbidden_display_terms(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_verifier_owner_review_packet()) + snapshot["operator_actions"][0]["operator_instruction"] = "不要顯示 work_window_transcript" + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="forbidden display terms leaked"): + load_latest_ai_agent_result_capture_release_verifier_owner_review_packet(tmp_path) + + +def _write_snapshot(directory: Path, payload: dict) -> None: + path = directory / "ai_agent_result_capture_release_verifier_owner_review_packet_2099-01-01.json" + path.write_text(json.dumps(payload, ensure_ascii=False), encoding="utf-8") diff --git a/apps/api/tests/test_ai_agent_result_capture_release_verifier_owner_review_packet_api.py b/apps/api/tests/test_ai_agent_result_capture_release_verifier_owner_review_packet_api.py new file mode 100644 index 000000000..fd3568c95 --- /dev/null +++ b/apps/api/tests/test_ai_agent_result_capture_release_verifier_owner_review_packet_api.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from fastapi.testclient import TestClient + +from src.main import app + + +def test_release_verifier_owner_review_packet_endpoint() -> None: + client = TestClient(app) + + response = client.get("/api/v1/agents/agent-result-capture-release-verifier-owner-review-packet") + + assert response.status_code == 200 + payload = response.json() + assert payload["schema_version"] == "ai_agent_result_capture_release_verifier_owner_review_packet_v1" + assert payload["program_status"]["current_task_id"] == "P2-137" + assert payload["program_status"]["next_task_id"] == "P2-138" + assert payload["program_status"]["overall_completion_percent"] == 100 + assert payload["program_status"]["runtime_authority"] == "result_capture_release_verifier_owner_review_packet_only_no_live_write" + assert payload["rollups"]["owner_review_packet_count"] == 5 + assert payload["rollups"]["verifier_review_packet_count"] == 5 + assert payload["rollups"]["rollback_owner_review_packet_count"] == 5 + assert payload["rollups"]["maintenance_window_review_hold_count"] == 5 + assert payload["rollups"]["live_apply_owner_review_hold_count"] == 5 + assert payload["rollups"]["blocked_owner_review_transition_count"] == 6 + assert payload["rollups"]["operator_action_count"] == 5 + assert payload["rollups"]["owner_release_authorized_count"] == 0 + assert payload["rollups"]["owner_review_approved_count"] == 0 + assert payload["rollups"]["release_authorization_granted_count"] == 0 + assert payload["rollups"]["release_authorization_pass_count"] == 0 + assert payload["rollups"]["gateway_queue_write_count"] == 0 + assert payload["rollups"]["telegram_send_count"] == 0 + assert payload["rollups"]["production_write_count"] == 0 diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index dcd45300d..90a6d7dfe 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -6143,6 +6143,42 @@ "runtimeWriteAllowed": "runtime 寫入允許={value}" } }, + "resultCaptureReleaseVerifierOwnerReviewPacket": { + "title": "P2-137 釋出驗證器負責人審查包", + "source": "產生 {generated};目前 {current};下一步 {next}", + "priorTitle": "前一關釋出驗證器預檢", + "truthTitle": "負責人審查包真相", + "metrics": { + "overall": "完成度", + "ownerPackets": "負責人審查包", + "verifierPackets": "驗證器審查包", + "rollbackPackets": "回滾 owner 審查", + "maintenanceHolds": "維護窗口保留", + "liveApplyHolds": "正式套用保留", + "blockers": "已阻擋轉換", + "actions": "操作選項", + "approvalRequired": "需批准", + "blocked": "阻擋", + "liveWrites": "正式寫入 / 發送" + }, + "flags": { + "p2Loaded": "已載入 P2-136={value}", + "ownerPacketReady": "負責人審查包已就緒={value}", + "liveApplyReviewRequired": "正式套用審查必要={value}" + }, + "labels": { + "ownerReleaseAuthorized": "負責人釋出授權={value}", + "ownerReviewApproved": "負責人審查通過={value}", + "authorizationGranted": "釋出授權已核發={value}", + "authorizationPassed": "釋出授權通過={value}", + "gatewayWrites": "Gateway 寫入={value}", + "postReleaseVerifierReady": "釋出後驗證器就緒={value}", + "rollbackOwnerConfirmed": "回滾 owner 已確認={value}", + "rollbackPassed": "回滾釋出通過={value}", + "liveApplyReleaseEnabled": "正式套用釋出啟用={value}", + "runtimeWriteAllowed": "runtime 寫入允許={value}" + } + }, "resultCaptureReleaseVerifierPreflightGate": { "title": "P2-136 釋出驗證器預檢關卡", "source": "產生 {generated};目前 {current};下一步 {next}", diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index dcd45300d..90a6d7dfe 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -6143,6 +6143,42 @@ "runtimeWriteAllowed": "runtime 寫入允許={value}" } }, + "resultCaptureReleaseVerifierOwnerReviewPacket": { + "title": "P2-137 釋出驗證器負責人審查包", + "source": "產生 {generated};目前 {current};下一步 {next}", + "priorTitle": "前一關釋出驗證器預檢", + "truthTitle": "負責人審查包真相", + "metrics": { + "overall": "完成度", + "ownerPackets": "負責人審查包", + "verifierPackets": "驗證器審查包", + "rollbackPackets": "回滾 owner 審查", + "maintenanceHolds": "維護窗口保留", + "liveApplyHolds": "正式套用保留", + "blockers": "已阻擋轉換", + "actions": "操作選項", + "approvalRequired": "需批准", + "blocked": "阻擋", + "liveWrites": "正式寫入 / 發送" + }, + "flags": { + "p2Loaded": "已載入 P2-136={value}", + "ownerPacketReady": "負責人審查包已就緒={value}", + "liveApplyReviewRequired": "正式套用審查必要={value}" + }, + "labels": { + "ownerReleaseAuthorized": "負責人釋出授權={value}", + "ownerReviewApproved": "負責人審查通過={value}", + "authorizationGranted": "釋出授權已核發={value}", + "authorizationPassed": "釋出授權通過={value}", + "gatewayWrites": "Gateway 寫入={value}", + "postReleaseVerifierReady": "釋出後驗證器就緒={value}", + "rollbackOwnerConfirmed": "回滾 owner 已確認={value}", + "rollbackPassed": "回滾釋出通過={value}", + "liveApplyReleaseEnabled": "正式套用釋出啟用={value}", + "runtimeWriteAllowed": "runtime 寫入允許={value}" + } + }, "resultCaptureReleaseVerifierPreflightGate": { "title": "P2-136 釋出驗證器預檢關卡", "source": "產生 {generated};目前 {current};下一步 {next}", diff --git a/apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx b/apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx index 3b280bd93..ebf899ece 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 @@ -85,6 +85,7 @@ import { type AiAgentResultCaptureReleaseAuthorizationHoldSnapshot, type AiAgentResultCaptureReleaseAuthorizationReadbackGateSnapshot, type AiAgentResultCaptureReleaseVerifierPreflightGateSnapshot, + type AiAgentResultCaptureReleaseVerifierOwnerReviewPacketSnapshot, type AiAgentResultCaptureWriterImplementationReviewSnapshot, type AiAgentOwnerApprovedFixturePromotionGateSnapshot, type AiAgentRuntimeWorkerShadowGateSnapshot, @@ -492,6 +493,7 @@ export function AutomationInventoryTab() { const [resultCaptureReleaseAuthorizationHold, setResultCaptureReleaseAuthorizationHold] = useState(null) const [resultCaptureReleaseAuthorizationReadbackGate, setResultCaptureReleaseAuthorizationReadbackGate] = useState(null) const [resultCaptureReleaseVerifierPreflightGate, setResultCaptureReleaseVerifierPreflightGate] = useState(null) + const [resultCaptureReleaseVerifierOwnerReviewPacket, setResultCaptureReleaseVerifierOwnerReviewPacket] = useState(null) const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState(null) const [ownerDryRunPackage, setOwnerDryRunPackage] = useState(null) const [hostStatefulInventory, setHostStatefulInventory] = useState(null) @@ -565,6 +567,7 @@ export function AutomationInventoryTab() { apiClient.getAiAgentResultCaptureReleaseAuthorizationHold(), apiClient.getAiAgentResultCaptureReleaseAuthorizationReadbackGate(), apiClient.getAiAgentResultCaptureReleaseVerifierPreflightGate(), + apiClient.getAiAgentResultCaptureReleaseVerifierOwnerReviewPacket(), apiClient.getAiAgentReportTruthActionabilityReview(), apiClient.getAiAgentOwnerApprovedFixtureDryRun(), apiClient.getAiAgentHostStatefulVersionInventory(), @@ -637,6 +640,7 @@ export function AutomationInventoryTab() { resultCaptureReleaseAuthorizationHoldResult, resultCaptureReleaseAuthorizationReadbackGateResult, resultCaptureReleaseVerifierPreflightGateResult, + resultCaptureReleaseVerifierOwnerReviewPacketResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -706,6 +710,7 @@ export function AutomationInventoryTab() { setResultCaptureReleaseAuthorizationHold(resultCaptureReleaseAuthorizationHoldResult.status === 'fulfilled' ? resultCaptureReleaseAuthorizationHoldResult.value : null) setResultCaptureReleaseAuthorizationReadbackGate(resultCaptureReleaseAuthorizationReadbackGateResult.status === 'fulfilled' ? resultCaptureReleaseAuthorizationReadbackGateResult.value : null) setResultCaptureReleaseVerifierPreflightGate(resultCaptureReleaseVerifierPreflightGateResult.status === 'fulfilled' ? resultCaptureReleaseVerifierPreflightGateResult.value : null) + setResultCaptureReleaseVerifierOwnerReviewPacket(resultCaptureReleaseVerifierOwnerReviewPacketResult.status === 'fulfilled' ? resultCaptureReleaseVerifierOwnerReviewPacketResult.value : null) setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null) setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null) setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null) @@ -773,6 +778,7 @@ export function AutomationInventoryTab() { resultCaptureReleaseAuthorizationHoldResult, resultCaptureReleaseAuthorizationReadbackGateResult, resultCaptureReleaseVerifierPreflightGateResult, + resultCaptureReleaseVerifierOwnerReviewPacketResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -2015,7 +2021,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 || !reportLiveDeliveryApprovalPackage || !runtimeReadbackFixtureApproval || !runtimeReadbackPromotionGate || !ownerApprovedFixturePromotionGate || !canonicalRuntimeReadbackOwnerAcceptance || !failureReceiptNoSendReplay || !reviewerQueueNoWriteReadback || !resultCaptureNoWriteReadback || !resultCapturePromotionApprovalGate || !ownerApprovedResultCapturePromotionDryRun || !resultCaptureWriteGateReview || !resultCaptureWriterImplementationReview || !resultCaptureWriterDryRunFixture || !resultCaptureWriterDryRunReadback || !resultCaptureOwnerPromotionReview || !resultCaptureOwnerApprovedExecutionRehearsal || !resultCaptureOwnerAcceptanceMaintenanceGate || !resultCaptureOwnerAcceptanceReadbackPreflightHold || !resultCaptureOwnerApprovedPreflightReleasePackage || !resultCaptureOwnerApprovedReleaseReadinessReadback || !resultCaptureOwnerReleaseApprovalGate || !resultCapturePostReleaseVerifierRollbackGate || !resultCaptureFinalReleaseCandidateReadback || !resultCaptureReleaseAuthorizationHold || !resultCaptureReleaseAuthorizationReadbackGate || !resultCaptureReleaseVerifierPreflightGate || !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 || !runtimeReadbackFixtureApproval || !runtimeReadbackPromotionGate || !ownerApprovedFixturePromotionGate || !canonicalRuntimeReadbackOwnerAcceptance || !failureReceiptNoSendReplay || !reviewerQueueNoWriteReadback || !resultCaptureNoWriteReadback || !resultCapturePromotionApprovalGate || !ownerApprovedResultCapturePromotionDryRun || !resultCaptureWriteGateReview || !resultCaptureWriterImplementationReview || !resultCaptureWriterDryRunFixture || !resultCaptureWriterDryRunReadback || !resultCaptureOwnerPromotionReview || !resultCaptureOwnerApprovedExecutionRehearsal || !resultCaptureOwnerAcceptanceMaintenanceGate || !resultCaptureOwnerAcceptanceReadbackPreflightHold || !resultCaptureOwnerApprovedPreflightReleasePackage || !resultCaptureOwnerApprovedReleaseReadinessReadback || !resultCaptureOwnerReleaseApprovalGate || !resultCapturePostReleaseVerifierRollbackGate || !resultCaptureFinalReleaseCandidateReadback || !resultCaptureReleaseAuthorizationHold || !resultCaptureReleaseAuthorizationReadbackGate || !resultCaptureReleaseVerifierPreflightGate || !resultCaptureReleaseVerifierOwnerReviewPacket || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { return (
@@ -3263,6 +3269,43 @@ export function AutomationInventoryTab() { + resultCaptureReleaseVerifierPreflightGate.rollups.playbook_trust_write_count + resultCaptureReleaseVerifierPreflightGate.rollups.production_write_count ) + const resultCaptureReleaseVerifierOwnerReviewOverall = resultCaptureReleaseVerifierOwnerReviewPacket.program_status.overall_completion_percent + const resultCaptureReleaseVerifierOwnerPackets = resultCaptureReleaseVerifierOwnerReviewPacket.rollups.owner_review_packet_count + const resultCaptureReleaseVerifierReviewPackets = resultCaptureReleaseVerifierOwnerReviewPacket.rollups.verifier_review_packet_count + const resultCaptureReleaseVerifierRollbackPackets = resultCaptureReleaseVerifierOwnerReviewPacket.rollups.rollback_owner_review_packet_count + const resultCaptureReleaseVerifierOwnerMaintenanceHolds = resultCaptureReleaseVerifierOwnerReviewPacket.rollups.maintenance_window_review_hold_count + const resultCaptureReleaseVerifierOwnerLiveApplyHolds = resultCaptureReleaseVerifierOwnerReviewPacket.rollups.live_apply_owner_review_hold_count + const resultCaptureReleaseVerifierOwnerBlockedTransitions = resultCaptureReleaseVerifierOwnerReviewPacket.rollups.blocked_owner_review_transition_count + const resultCaptureReleaseVerifierOwnerActions = resultCaptureReleaseVerifierOwnerReviewPacket.rollups.operator_action_count + const resultCaptureReleaseVerifierOwnerApprovalRequired = ( + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.approval_required_owner_review_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.approval_required_verifier_review_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.approval_required_rollback_owner_review_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.approval_required_maintenance_window_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.approval_required_live_apply_review_count + ) + const resultCaptureReleaseVerifierOwnerBlocked = ( + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.blocked_owner_review_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.blocked_verifier_review_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.blocked_rollback_owner_review_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.blocked_maintenance_window_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.blocked_live_apply_review_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.critical_blocker_count + ) + const resultCaptureReleaseVerifierOwnerLiveWrites = ( + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.writer_apply_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.execution_apply_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.receipt_write_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.reviewer_queue_write_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.gateway_queue_write_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.telegram_send_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.bot_api_call_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.report_receipt_write_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.result_capture_write_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.learning_write_count + + resultCaptureReleaseVerifierOwnerReviewPacket.rollups.playbook_trust_write_count + + resultCaptureReleaseVerifierOwnerReviewPacket.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 @@ -7823,6 +7866,152 @@ export function AutomationInventoryTab() {
+
+
+
+ + + {t('resultCaptureReleaseVerifierOwnerReviewPacket.title')} + +
+ +
+ +
+ } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> +
+ +
+
+ {t('resultCaptureReleaseVerifierOwnerReviewPacket.priorTitle')} +

+ {resultCaptureReleaseVerifierOwnerReviewPacket.prior_release_verifier_preflight_gate.readiness_note} +

+
+ + + +
+
+ +
+ {t('resultCaptureReleaseVerifierOwnerReviewPacket.truthTitle')} +

+ {resultCaptureReleaseVerifierOwnerReviewPacket.release_verifier_owner_review_truth.truth_note} +

+
+ + + + + + +
+
+
+ +
+ {resultCaptureReleaseVerifierOwnerReviewPacket.owner_review_packets.slice(0, 5).map(packet => ( +
+
+ + {packet.display_name} + + +
+ + {packet.review_summary} + +
+ + + + + +
+
+ ))} +
+ +
+ {resultCaptureReleaseVerifierOwnerReviewPacket.verifier_review_packets.slice(0, 5).map(packet => ( +
+
+ + {packet.display_name} + + +
+ + {packet.verifier_summary} + +
+ + + + +
+
+ ))} +
+ +
+ {resultCaptureReleaseVerifierOwnerReviewPacket.blocked_owner_review_transitions.slice(0, 6).map(transition => ( +
+
+ + {transition.transition_id} + + +
+ + {transition.reason} + +
+ +
+
+ ))} +
+ +
+ {resultCaptureReleaseVerifierOwnerReviewPacket.operator_actions.slice(0, 5).map(action => ( +
+
+ + {action.action_id} + + +
+ + {action.operator_instruction} + +
+ + +
+
+ ))} +
+
+
diff --git a/apps/web/src/lib/api-client.ts b/apps/web/src/lib/api-client.ts index 98f8c79a1..bc3f65027 100644 --- a/apps/web/src/lib/api-client.ts +++ b/apps/web/src/lib/api-client.ts @@ -580,6 +580,11 @@ export const apiClient = { return handleResponse(res) }, + async getAiAgentResultCaptureReleaseVerifierOwnerReviewPacket() { + const res = await fetch(`${API_BASE_URL}/agents/agent-result-capture-release-verifier-owner-review-packet`) + return handleResponse(res) + }, + async getAiAgentOwnerApprovedFixtureDryRun() { const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`) return handleResponse(res) @@ -8853,6 +8858,249 @@ export interface AiAgentResultCaptureReleaseVerifierPreflightGateSnapshot { } } +export interface AiAgentResultCaptureReleaseVerifierOwnerReviewPacketSnapshot { + schema_version: 'ai_agent_result_capture_release_verifier_owner_review_packet_v1' + generated_at: string + program_status: { + overall_completion_percent: number + current_priority: 'P0' | 'P1' | 'P2' | 'P3' + current_task_id: 'P2-137' + next_task_id: 'P2-138' + read_only_mode: true + runtime_authority: 'result_capture_release_verifier_owner_review_packet_only_no_live_write' + status_note: string + } + source_refs: string[] + prior_release_verifier_preflight_gate: { + schema_version: string + release_verifier_preflight_count: number + rollback_verifier_preflight_count: number + maintenance_window_verifier_hold_count: number + live_apply_verifier_hold_count: number + blocked_verifier_preflight_transition_count: number + operator_action_count: number + approval_required_total: number + blocked_total: number + owner_release_authorized_count: number + owner_release_approved_count: number + owner_review_approved_count: number + maintenance_window_approved_count: number + rollback_owner_confirmed_count: number + post_release_verifier_ready_count: number + final_release_candidate_approved_count: number + final_release_candidate_pass_count: number + release_authorization_granted_count: number + release_authorization_pass_count: number + rollback_release_pass_count: number + live_apply_release_pass_count: number + writer_apply_count: number + execution_apply_count: number + receipt_write_count: number + result_capture_write_count: number + learning_write_count: number + playbook_trust_write_count: number + reviewer_queue_write_count: number + gateway_queue_write_count: number + telegram_send_count: number + bot_api_call_count: number + report_receipt_write_count: number + production_write_count: number + secret_read_count: number + destructive_operation_count: number + readiness_note: string + } + release_verifier_owner_review_truth: { + p2_136_release_verifier_preflight_gate_loaded: boolean + owner_review_packet_ready: boolean + release_verifier_review_required: boolean + rollback_owner_review_required: boolean + maintenance_window_review_required: boolean + live_apply_review_required: boolean + redaction_review_required: boolean + owner_review_packet_only: boolean + owner_release_authorized: boolean + owner_release_approved: boolean + owner_review_approved: boolean + maintenance_window_approved: boolean + rollback_owner_confirmed: boolean + post_release_verifier_ready: boolean + final_release_candidate_approved: boolean + final_release_candidate_passed: boolean + release_authorization_granted: boolean + release_authorization_passed: boolean + rollback_release_passed: boolean + live_apply_release_passed: boolean + writer_apply_enabled: boolean + execution_apply_enabled: boolean + receipt_write_enabled: boolean + reviewer_queue_write_enabled: boolean + gateway_queue_write_enabled: boolean + telegram_send_enabled: boolean + bot_api_call_enabled: boolean + report_receipt_write_enabled: boolean + result_capture_write_enabled: boolean + learning_write_enabled: boolean + playbook_trust_write_enabled: boolean + production_write_enabled: boolean + secret_read_enabled: boolean + destructive_operation_enabled: boolean + owner_release_authorized_count: number + owner_release_approved_count: number + owner_review_approved_count: number + maintenance_window_approved_count: number + rollback_owner_confirmed_count: number + post_release_verifier_ready_count: number + final_release_candidate_approved_count: number + final_release_candidate_pass_count: number + release_authorization_granted_count: number + release_authorization_pass_count: number + rollback_release_pass_count: number + live_apply_release_pass_count: number + writer_apply_count: number + execution_apply_count: number + receipt_write_count: number + reviewer_queue_write_count: number + gateway_queue_write_count: number + telegram_send_count: number + bot_api_call_count: number + report_receipt_write_count: number + result_capture_write_count: number + learning_write_count: number + playbook_trust_write_count: number + production_write_count: number + secret_read_count: number + destructive_operation_count: number + truth_note: string + } + owner_review_packets: Array<{ + packet_id: string + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + source_readback_id: string + status: 'ready_for_owner_review' | 'approval_required' | 'blocked_by_policy' + packet_mode: 'release_verifier_owner_review_packet' + owner_release_authorized: false + owner_review_approved: false + release_authorization_granted: false + release_authorization_passed: false + review_summary: string + evidence_hash: string + }> + verifier_review_packets: Array<{ + packet_id: string + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + status: 'ready_for_owner_review' | 'approval_required' | 'blocked_by_policy' + packet_mode: 'release_verifier_review_packet' + post_release_verifier_required: true + post_release_verifier_ready: false + release_authorization_passed: false + verifier_summary: string + }> + rollback_owner_review_packets: Array<{ + packet_id: string + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + status: 'ready_for_owner_review' | 'approval_required' | 'blocked_by_policy' + packet_mode: 'rollback_owner_review_packet' + rollback_owner_required: true + rollback_owner_confirmed: false + rollback_release_passed: false + rollback_summary: string + }> + maintenance_window_review_holds: Array<{ + hold_id: string + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + status: 'ready_for_owner_review' | 'approval_required' | 'blocked_by_policy' + hold_mode: 'maintenance_window_owner_review_hold' + owner_release_authorized: false + maintenance_window_required: true + maintenance_window_approved: false + hold_reason: string + }> + live_apply_owner_review_holds: Array<{ + hold_id: string + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + status: 'ready_for_owner_review' | 'approval_required' | 'blocked_by_policy' + hold_mode: 'live_apply_owner_review_hold' + release_authorization_granted: false + release_authorization_passed: false + live_apply_release_passed: false + live_apply_release_enabled: false + release_condition: string + }> + blocked_owner_review_transitions: Array<{ + transition_id: string + status: 'blocked_by_policy' | 'approval_required' + reason: string + runtime_write_allowed: false + }> + operator_actions: Array<{ + action_id: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + status: 'ready_for_operator_review' | 'approval_required' + operator_instruction: string + runtime_write_allowed: false + }> + display_redaction_contract: { + redaction_required: true + raw_prompt_display_allowed: false + private_reasoning_display_allowed: false + secret_value_display_allowed: false + raw_runtime_payload_display_allowed: false + internal_collaboration_content_display_allowed: false + frontend_display_policy: string + } + rollups: { + owner_review_packet_count: number + verifier_review_packet_count: number + rollback_owner_review_packet_count: number + maintenance_window_review_hold_count: number + live_apply_owner_review_hold_count: number + blocked_owner_review_transition_count: number + operator_action_count: number + approval_required_owner_review_count: number + blocked_owner_review_count: number + approval_required_verifier_review_count: number + blocked_verifier_review_count: number + approval_required_rollback_owner_review_count: number + blocked_rollback_owner_review_count: number + approval_required_maintenance_window_count: number + blocked_maintenance_window_count: number + approval_required_live_apply_review_count: number + blocked_live_apply_review_count: number + critical_blocker_count: number + owner_release_authorized_count: number + owner_release_approved_count: number + owner_review_approved_count: number + maintenance_window_approved_count: number + rollback_owner_confirmed_count: number + post_release_verifier_ready_count: number + final_release_candidate_approved_count: number + final_release_candidate_pass_count: number + release_authorization_granted_count: number + release_authorization_pass_count: number + rollback_release_pass_count: number + live_apply_release_pass_count: number + writer_apply_count: number + execution_apply_count: number + receipt_write_count: number + reviewer_queue_write_count: number + gateway_queue_write_count: number + telegram_send_count: number + bot_api_call_count: number + report_receipt_write_count: number + result_capture_write_count: number + learning_write_count: number + playbook_trust_write_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 d164f0063..dd211a4db 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,26 @@ +## 2026-06-14|P2-137 釋出驗證器負責人審查包本地完成 + +**背景**:P2-136 release verifier preflight gate 已正式驗證完成,但 verifier preflight 仍不得被誤讀成 post-release verifier ready、release authorization granted / passed、rollback release passed 或 live apply release passed。P2-137 因此只把 P2-136 預檢結果整理成 owner / verifier review packet,讓後續 owner decision hold 可讀回,不核發授權、不套用 writer、不寫 queue、不送 Telegram。 + +**完成內容**: +- 新增 `ai_agent_result_capture_release_verifier_owner_review_packet_v1` schema、committed snapshot、loader 與 API endpoint `GET /api/v1/agents/agent-result-capture-release-verifier-owner-review-packet`。 +- P2-137 snapshot 固定 5 個 owner review packet、5 個 verifier review packet、5 個 rollback owner review packet、5 個 maintenance window review hold、5 個 live-apply owner review hold、6 個 blocked owner review transition 與 5 個 operator action。 +- Governance automation inventory 頁新增 P2-137 區塊,顯示 P2-137 進度 `100%`、負責人審查包 `5`、驗證器審查包 `5`、回滾 owner 審查 `5`、維護窗口保留 `5`、正式套用保留 `5`、已阻擋轉換 `6`、operator action `5`、需批准 `10`、阻擋 `10`、正式寫入 / 發送 `0`。 +- Release verifier owner review truth 固定為 `result_capture_release_verifier_owner_review_packet_only_no_live_write`;owner release authorized、owner release approved、owner review approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API、report receipt、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive operation 仍全部維持 `0 / false`。 + +**本地驗證**: +- JSON parse:P2-137 schema / snapshot、`zh-TW.json`、`en.json` 通過。 +- Python 編譯:P2-137 loader 與 `agents.py` 通過。 +- API/service pytest:P2-137 `7 passed`。 +- Web typecheck:`pnpm --filter @awoooi/web typecheck` 通過。 + +**安全邊界**: +- P2-137 仍是只讀 owner / verifier review packet;不接受口頭批准、不把 review packet 解讀成 owner release authorized、不批准維護窗口、不確認 rollback owner、不通過 post-release verifier、不核發 release authorization、不通過 release authorization、不通過 rollback release、不釋放 live apply、不套用 writer、不執行正式寫入、不寫 receipt、不寫 result capture、不寫 learning、不更新 PlayBook trust、不寫 reviewer queue、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不讀 canonical runtime target、不做 live query、不寫 production target、不讀 secret、不執行 destructive action、不回傳內部工作內容。 +- 本段尚未正式部署;需要 feature commit、deploy marker、production API readback 與 desktop / mobile Browser smoke 後,才可記錄正式驗證完成。 + +**下一步**: +- `P2-138`:release decision hold;只能承接 P2-137 的只讀審查包,仍不得直接開啟 result capture writer、learning writer、PlayBook trust writer、reviewer queue write、Gateway queue write、Telegram send、Bot API call 或 production write。 + ## 2026-06-14|P2-136 / AI Agent 活動正式 deploy 後 recovery readback 無回歸 **背景**:另一工作視窗已把 P2-136 / AI Agent 動畫正式驗證文件推到 `gitea/main=a0fe7741`;runtime deploy marker 仍是 `60a0415c chore(cd): deploy a3de0ff [skip ci]`,對應 feature commit `a3de0ffb feat(governance): 新增 AI Agent 活動動畫`。本輪只從 reboot / cold-start / backup recovery 角度做只讀 readback,不重複修改 P2-136 或 AI Agent 活動動畫治理程式,不手動建立 / 刪除 / patch `km-vectorize` Job。 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 2c7ca000d..fe9dec789 100644 --- a/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md +++ b/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md @@ -52,13 +52,21 @@ - 邊界仍維持:post-release verifier ready、release authorization granted / passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、result capture write、learning write、PlayBook trust write、reviewer queue write、Gateway queue write、Telegram send、Bot API、production write、secret read、destructive operation 全部 `0 / false`。 - 真正下一步是 `P2-137` owner / verifier review packet;仍不得直接開啟 result capture writer、learning writer、PlayBook trust writer、reviewer queue write、Gateway queue write、Telegram send、Bot API call 或 production write。 +### 2026-06-14 10:12 狀態同步 + +- `P2-137` release verifier owner review packet 已本地完成:新增 `ai_agent_result_capture_release_verifier_owner_review_packet_v1`、`GET /api/v1/agents/agent-result-capture-release-verifier-owner-review-packet`、治理頁 P2-137 區塊與繁中 UI 文案。 +- 本地證據:P2-137 API/service pytest `7 passed`、JSON parse、Python compile、Web typecheck 通過。 +- P2-137 固定 5 個 owner review packet、5 個 verifier review packet、5 個 rollback owner review packet、5 個 maintenance window review hold、5 個 live-apply owner review hold、6 個 blocked owner review transition、5 個 operator action、需批准 `10`、阻擋 `10`、正式寫入 / 發送 `0`。 +- 邊界仍維持:owner release authorized、owner review approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release authorization granted / passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、result capture write、learning write、PlayBook trust write、reviewer queue write、Gateway queue write、Telegram send、Bot API、production write、secret read、destructive operation 全部 `0 / false`。 +- P2-137 尚未正式部署;推送、deploy marker、production API readback 與 desktop / mobile smoke 完成後,才可由 `P2-138` release decision hold 承接。 + AI Agent 自動化工作包目前完成度:**99.8%**。本工作清單文件本身完成度:**100%**。 三 Agent 佈建布局目前完成度:**45%**。第一波已完成只讀 schema / snapshot / API / 測試 / 報告,第二波已接入治理頁自動化盤點 UI;正式 runtime 佈署、Telegram E2E 發送與 AgentSession 工作流仍需逐項 gate。 -三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。P2-403A 到 P2-135 已把互動證據、報表治理、runtime readback、reviewer / result capture / writer gates、no-write readback、promotion review、writer implementation review、writer dry-run fixture、writer dry-run readback、owner promotion execution gate、owner-approved execution rehearsal、owner acceptance / maintenance window gate、owner acceptance readback / preflight hold、owner-approved preflight release package、owner-approved release readiness readback、owner release approval gate、post-release verifier / rollback gate、final release candidate readback、release authorization hold 與 release authorization readback gate 全部固定成可驗證證據。P2-135 已正式驗證;正式 API 回 `schema_version=ai_agent_result_capture_release_authorization_readback_gate_v1`、current `P2-135`、next `P2-136`、completion `100`、runtime authority `result_capture_release_authorization_readback_gate_only_no_live_write`;deploy marker `8d575c1a`,desktop / mobile smoke 均確認 P2-135 區塊可見。P2-134 已正式驗證,deploy marker `18b867c3`;desktop / mobile smoke 均確認 P2-134 區塊可見。目前 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-136`。 +三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。P2-403A 到 P2-137 已把互動證據、報表治理、runtime readback、reviewer / result capture / writer gates、no-write readback、promotion review、writer implementation review、writer dry-run fixture、writer dry-run readback、owner promotion execution gate、owner-approved execution rehearsal、owner acceptance / maintenance window gate、owner acceptance readback / preflight hold、owner-approved preflight release package、owner-approved release readiness readback、owner release approval gate、post-release verifier / rollback gate、final release candidate readback、release authorization hold、release authorization readback gate、release verifier preflight gate 與 release verifier owner review packet 固定成可驗證證據。P2-136 已正式驗證;P2-137 已本地完成但尚未正式部署。目前 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-137 正式驗證後的 `P2-138`。 -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-135` 已補互動、學習證據面、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 / readback、result capture writer dry-run fixture、writer dry-run readback、owner promotion execution gate、owner-approved execution rehearsal、owner acceptance / maintenance window gate、owner acceptance readback / preflight hold、owner-approved preflight release package、owner-approved release readiness readback、owner release approval gate、post-release verifier / rollback gate、final release candidate readback、release authorization hold 與 release authorization readback gate。下一步是 P2-135 正式驗證後的 `P2-136`;外部 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-137` 已補互動、學習證據面、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 / readback、result capture writer dry-run fixture、writer dry-run readback、owner promotion execution gate、owner-approved execution rehearsal、owner acceptance / maintenance window gate、owner acceptance readback / preflight hold、owner-approved preflight release package、owner-approved release readiness readback、owner release approval gate、post-release verifier / rollback gate、final release candidate readback、release authorization hold、release authorization readback gate、release verifier preflight gate 與 release verifier owner review packet。下一步是 P2-137 正式驗證後的 `P2-138`;外部 registry / package source / host probe / SSH / kubectl / 工具安裝 / CI 變更 / 實際 PR creation / Telegram 實發與 learning write 仍需 gate。 完成度計算模型: @@ -1045,7 +1053,8 @@ UI: | P2-134 | 完成 | 100 | OpenClaw + Hermes + NemoTron | release authorization hold | `ai_agent_result_capture_release_authorization_hold_v1` / schema / snapshot / 只讀 API / governance UI;正式站 deploy marker `18b867c3` 已驗證;5 個 release authorization hold、5 個 rollback authorization hold、5 個 release window hold、5 個 live-apply authorization hold、6 個 blocked authorization transition、5 個 operator action;runtime authority 固定 `result_capture_release_authorization_hold_only_no_live_write`;owner release authorized / maintenance window approved / rollback owner confirmed / release authorization granted / release authorization passed / live apply release passed / writer apply / execution apply / receipt write / result capture / learning / PlayBook trust / reviewer queue / Gateway / Telegram / Bot API / report receipt / production write / secret read / destructive operation 全為 `0`;desktop / mobile smoke 禁用內部協作片語 `0`、水平溢位 `0`、P2-134 區塊危險操作入口 `0`、console error `0`、critical network issue `0` | 已由 P2-135 承接;不把 authorization hold 視為正式授權、不釋放 live apply、不套用 writer、不寫 receipt、不寫 result capture、不寫 learning、不送 Telegram、不寫 production | | P2-135 | 完成 | 100 | OpenClaw + Hermes + NemoTron | release authorization readback gate | `ai_agent_result_capture_release_authorization_readback_gate_v1` / schema / snapshot / 只讀 API / governance UI;本地 pytest `14 passed`、JSON parse、Python compile、Web typecheck 通過;5 個 release authorization readback、5 個 rollback release readback、5 個 maintenance window readback hold、5 個 live-apply release readback hold、6 個 blocked release readback transition、5 個 operator action;runtime authority 固定 `result_capture_release_authorization_readback_gate_only_no_live_write`;owner release authorized、release authorization granted / passed、rollback release、live apply release、writer apply、execution apply、receipt write、result capture、learning、PlayBook trust、Gateway、Telegram、production write 全為 `0` | 正式站 deploy marker `8d575c1a` 已驗證;production API readback、desktop / mobile smoke、禁用內部協作片語 `0`、水平溢位 `0`、高風險控制 `0`、console error `0`;已由 P2-136 承接,不核發 release authorization、不釋放 live apply、不套用 writer | | P2-136 | 完成 | 100 | OpenClaw + Hermes + NemoTron | release verifier preflight gate | `ai_agent_result_capture_release_verifier_preflight_gate_v1` / schema / snapshot / 只讀 API / governance UI;feature commit `913d7f68`、deploy marker `f2fa8454` 已正式驗證;5 個 release verifier preflight、5 個 rollback verifier preflight、5 個 maintenance window verifier hold、5 個 live-apply verifier hold、6 個 blocked verifier preflight transition、5 個 operator action;需批准 `8`、blocked status subtotal `4`、critical blocker `5`、前端顯示阻擋總數 `9`;runtime authority 固定 `result_capture_release_verifier_preflight_gate_only_no_live_write`;post-release verifier ready、release authorization granted / passed、rollback release、live apply release、writer apply、execution apply、receipt write、result capture、learning、PlayBook trust、Gateway、Telegram、production write、secret read、destructive operation 全為 `0` | production API readback、desktop / mobile smoke、禁用內部協作片語 `0`、水平溢位 `0`、危險控制 `0`、console error `0`;已由 P2-137 承接,不把 verifier preflight 視為 post-release verifier ready、不核發 release authorization、不釋放 live apply、不套用 writer | -| P2-137 | 計畫中 | 0 | OpenClaw + Hermes + NemoTron | owner / verifier review packet | 承接 P2-136,只能建立 owner / verifier / rollback / maintenance window / live-apply review packet 的只讀證據;不得讀 secret、不得寫 reviewer queue、不得寫 Gateway queue、不得送 Telegram、不得呼叫 Bot API、不得 production write | `a3de0ffb` deploy marker 與 animation smoke 已收斂;下一步可開始 P2-137,但不可把 owner review packet 視為授權通過 | +| P2-137 | 本地完成 | 100 | OpenClaw + Hermes + NemoTron | release verifier owner review packet | `ai_agent_result_capture_release_verifier_owner_review_packet_v1` / schema / snapshot / 只讀 API / governance UI;5 個 owner review packet、5 個 verifier review packet、5 個 rollback owner review packet、5 個 maintenance window review hold、5 個 live-apply owner review hold、6 個 blocked owner review transition、5 個 operator action;需批准 `10`、阻擋 `10`;runtime authority 固定 `result_capture_release_verifier_owner_review_packet_only_no_live_write`;owner release authorized / owner review approved / maintenance window approved / rollback owner confirmed / post-release verifier ready / release authorization granted / release authorization passed / rollback release / live apply release / writer apply / execution apply / receipt write / result capture / learning / PlayBook trust / reviewer queue / Gateway / Telegram / Bot API / production write / secret read / destructive operation 全為 `0` | 本地 pytest `7 passed`、JSON parse、Python compile、Web typecheck 通過;尚未正式部署,正式 API readback 與 desktop / mobile smoke 完成後才可由 P2-138 承接 | +| P2-138 | 計畫中 | 0 | OpenClaw + Hermes + NemoTron | release decision hold | 承接 P2-137,只能建立 release decision hold 的只讀證據;不得把 owner review packet 視為授權通過,不得讀 secret、不得寫 reviewer queue、不得寫 Gateway queue、不得送 Telegram、不得呼叫 Bot API、不得 production write | 等 P2-137 feature commit、deploy marker、production API readback 與 Browser desktop / mobile smoke 完成後才可開始 | ### P3 - 候選 Agent 擴展 diff --git a/docs/evaluations/ai_agent_result_capture_release_verifier_owner_review_packet_2026-06-14.json b/docs/evaluations/ai_agent_result_capture_release_verifier_owner_review_packet_2026-06-14.json new file mode 100644 index 000000000..6c06a0c06 --- /dev/null +++ b/docs/evaluations/ai_agent_result_capture_release_verifier_owner_review_packet_2026-06-14.json @@ -0,0 +1,554 @@ +{ + "schema_version": "ai_agent_result_capture_release_verifier_owner_review_packet_v1", + "generated_at": "2026-06-14T09:35:00+08:00", + "program_status": { + "overall_completion_percent": 100, + "current_priority": "P2", + "current_task_id": "P2-137", + "next_task_id": "P2-138", + "read_only_mode": true, + "runtime_authority": "result_capture_release_verifier_owner_review_packet_only_no_live_write", + "status_note": "P2-137 只把 P2-136 release verifier preflight gate 整理成 owner review packet;不得視為 owner release authorized,不得核發 release authorization,不得通過 rollback release 或 live apply,不得套用 writer、寫 receipt、寫 result capture、寫 learning、寫 queue、送 Telegram 或寫入 production。" + }, + "source_refs": [ + "docs/evaluations/ai_agent_result_capture_release_verifier_preflight_gate_2026-06-14.json", + "docs/evaluations/ai_agent_result_capture_release_authorization_hold_2026-06-14.json", + "docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md#58-建立-release-verifier-owner-review-packet" + ], + "prior_release_verifier_preflight_gate": { + "schema_version": "ai_agent_result_capture_release_verifier_preflight_gate_v1", + "release_verifier_preflight_count": 5, + "rollback_verifier_preflight_count": 5, + "maintenance_window_verifier_hold_count": 5, + "live_apply_verifier_hold_count": 5, + "blocked_verifier_preflight_transition_count": 6, + "operator_action_count": 5, + "approval_required_total": 8, + "blocked_total": 9, + "owner_release_authorized_count": 0, + "owner_release_approved_count": 0, + "owner_review_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "final_release_candidate_approved_count": 0, + "final_release_candidate_pass_count": 0, + "release_authorization_granted_count": 0, + "release_authorization_pass_count": 0, + "rollback_release_pass_count": 0, + "live_apply_release_pass_count": 0, + "writer_apply_count": 0, + "execution_apply_count": 0, + "receipt_write_count": 0, + "reviewer_queue_write_count": 0, + "gateway_queue_write_count": 0, + "telegram_send_count": 0, + "bot_api_call_count": 0, + "report_receipt_write_count": 0, + "result_capture_write_count": 0, + "learning_write_count": 0, + "playbook_trust_write_count": 0, + "production_write_count": 0, + "secret_read_count": 0, + "destructive_operation_count": 0, + "readiness_note": "P2-136 已把 release verifier preflight、rollback release readback、maintenance window readback hold、live-apply release readback hold 與 blocked release readback transition 固定為只讀 gate;P2-137 只整理 owner review packet,不核發 release authorization。" + }, + "release_verifier_owner_review_truth": { + "p2_136_release_verifier_preflight_gate_loaded": true, + "owner_review_packet_ready": true, + "release_verifier_review_required": true, + "rollback_owner_review_required": true, + "maintenance_window_review_required": true, + "live_apply_review_required": true, + "redaction_review_required": true, + "owner_review_packet_only": true, + "owner_release_authorized": false, + "owner_release_approved": false, + "owner_review_approved": false, + "maintenance_window_approved": false, + "rollback_owner_confirmed": false, + "post_release_verifier_ready": false, + "final_release_candidate_approved": false, + "final_release_candidate_passed": false, + "release_authorization_granted": false, + "release_authorization_passed": false, + "rollback_release_passed": false, + "live_apply_release_passed": false, + "writer_apply_enabled": false, + "execution_apply_enabled": false, + "receipt_write_enabled": false, + "reviewer_queue_write_enabled": false, + "gateway_queue_write_enabled": false, + "telegram_send_enabled": false, + "bot_api_call_enabled": false, + "report_receipt_write_enabled": false, + "result_capture_write_enabled": false, + "learning_write_enabled": false, + "playbook_trust_write_enabled": false, + "production_write_enabled": false, + "secret_read_enabled": false, + "destructive_operation_enabled": false, + "owner_release_authorized_count": 0, + "owner_release_approved_count": 0, + "owner_review_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "final_release_candidate_approved_count": 0, + "final_release_candidate_pass_count": 0, + "release_authorization_granted_count": 0, + "release_authorization_pass_count": 0, + "rollback_release_pass_count": 0, + "live_apply_release_pass_count": 0, + "writer_apply_count": 0, + "execution_apply_count": 0, + "receipt_write_count": 0, + "reviewer_queue_write_count": 0, + "gateway_queue_write_count": 0, + "telegram_send_count": 0, + "bot_api_call_count": 0, + "report_receipt_write_count": 0, + "result_capture_write_count": 0, + "learning_write_count": 0, + "playbook_trust_write_count": 0, + "production_write_count": 0, + "secret_read_count": 0, + "destructive_operation_count": 0, + "truth_note": "P2-137 只整理 owner review packet;packet 可見不代表 owner release authorized、release authorization granted / passed、rollback release passed 或 live apply release passed。" + }, + "owner_review_packets": [ + { + "packet_id": "owner_review_packet_result_capture", + "display_name": "Result capture 負責人審查包", + "owner_agent": "openclaw", + "source_readback_id": "release_verifier_preflight_result_capture", + "status": "ready_for_owner_review", + "packet_mode": "release_verifier_owner_review_packet", + "owner_release_authorized": false, + "owner_review_approved": false, + "release_authorization_granted": false, + "release_authorization_passed": false, + "review_summary": "整理 Result capture release verifier preflight 為 owner review packet;仍未取得 owner release authorization、maintenance window、rollback owner 與 release authorization pass,不得寫入或發送。", + "evidence_hash": "sha256:8211111111111111111111111111111111111111111111111111111111111111" + }, + { + "packet_id": "owner_review_packet_learning", + "display_name": "Learning 負責人審查包", + "owner_agent": "hermes", + "source_readback_id": "release_verifier_preflight_learning", + "status": "approval_required", + "packet_mode": "release_verifier_owner_review_packet", + "owner_release_authorized": false, + "owner_review_approved": false, + "release_authorization_granted": false, + "release_authorization_passed": false, + "review_summary": "整理 Learning release verifier preflight 為 owner review packet;仍未取得 owner release authorization、maintenance window、rollback owner 與 release authorization pass,不得寫入或發送。", + "evidence_hash": "sha256:8222222222222222222222222222222222222222222222222222222222222222" + }, + { + "packet_id": "owner_review_packet_playbook_trust", + "display_name": "PlayBook trust 負責人審查包", + "owner_agent": "nemotron", + "source_readback_id": "release_verifier_preflight_playbook_trust", + "status": "blocked_by_policy", + "packet_mode": "release_verifier_owner_review_packet", + "owner_release_authorized": false, + "owner_review_approved": false, + "release_authorization_granted": false, + "release_authorization_passed": false, + "review_summary": "整理 PlayBook trust release verifier preflight 為 owner review packet;仍未取得 owner release authorization、maintenance window、rollback owner 與 release authorization pass,不得寫入或發送。", + "evidence_hash": "sha256:8233333333333333333333333333333333333333333333333333333333333333" + }, + { + "packet_id": "owner_review_packet_reviewer_queue", + "display_name": "Reviewer queue 負責人審查包", + "owner_agent": "openclaw", + "source_readback_id": "release_verifier_preflight_reviewer_queue", + "status": "approval_required", + "packet_mode": "release_verifier_owner_review_packet", + "owner_release_authorized": false, + "owner_review_approved": false, + "release_authorization_granted": false, + "release_authorization_passed": false, + "review_summary": "整理 Reviewer queue release verifier preflight 為 owner review packet;仍未取得 owner release authorization、maintenance window、rollback owner 與 release authorization pass,不得寫入或發送。", + "evidence_hash": "sha256:8244444444444444444444444444444444444444444444444444444444444444" + }, + { + "packet_id": "owner_review_packet_gateway_queue", + "display_name": "Gateway queue 負責人審查包", + "owner_agent": "nemotron", + "source_readback_id": "release_verifier_preflight_gateway_queue", + "status": "ready_for_owner_review", + "packet_mode": "release_verifier_owner_review_packet", + "owner_release_authorized": false, + "owner_review_approved": false, + "release_authorization_granted": false, + "release_authorization_passed": false, + "review_summary": "整理 Gateway queue release verifier preflight 為 owner review packet;仍未取得 owner release authorization、maintenance window、rollback owner 與 release authorization pass,不得寫入或發送。", + "evidence_hash": "sha256:8255555555555555555555555555555555555555555555555555555555555555" + } + ], + "verifier_review_packets": [ + { + "packet_id": "verifier_review_packet_result_capture", + "display_name": "Result capture 驗證器審查包", + "owner_agent": "openclaw", + "status": "ready_for_owner_review", + "packet_mode": "release_verifier_review_packet", + "post_release_verifier_required": true, + "post_release_verifier_ready": false, + "release_authorization_passed": false, + "verifier_summary": "整理 Result capture release verifier review;verifier 未 ready 前不得通過 release authorization。" + }, + { + "packet_id": "verifier_review_packet_learning", + "display_name": "Learning 驗證器審查包", + "owner_agent": "hermes", + "status": "approval_required", + "packet_mode": "release_verifier_review_packet", + "post_release_verifier_required": true, + "post_release_verifier_ready": false, + "release_authorization_passed": false, + "verifier_summary": "整理 Learning release verifier review;verifier 未 ready 前不得通過 release authorization。" + }, + { + "packet_id": "verifier_review_packet_playbook_trust", + "display_name": "PlayBook trust 驗證器審查包", + "owner_agent": "nemotron", + "status": "blocked_by_policy", + "packet_mode": "release_verifier_review_packet", + "post_release_verifier_required": true, + "post_release_verifier_ready": false, + "release_authorization_passed": false, + "verifier_summary": "整理 PlayBook trust release verifier review;verifier 未 ready 前不得通過 release authorization。" + }, + { + "packet_id": "verifier_review_packet_reviewer_queue", + "display_name": "Reviewer queue 驗證器審查包", + "owner_agent": "openclaw", + "status": "approval_required", + "packet_mode": "release_verifier_review_packet", + "post_release_verifier_required": true, + "post_release_verifier_ready": false, + "release_authorization_passed": false, + "verifier_summary": "整理 Reviewer queue release verifier review;verifier 未 ready 前不得通過 release authorization。" + }, + { + "packet_id": "verifier_review_packet_gateway_queue", + "display_name": "Gateway queue 驗證器審查包", + "owner_agent": "nemotron", + "status": "ready_for_owner_review", + "packet_mode": "release_verifier_review_packet", + "post_release_verifier_required": true, + "post_release_verifier_ready": false, + "release_authorization_passed": false, + "verifier_summary": "整理 Gateway queue release verifier review;verifier 未 ready 前不得通過 release authorization。" + } + ], + "rollback_owner_review_packets": [ + { + "packet_id": "rollback_owner_review_packet_result_capture", + "display_name": "Result capture 回滾 owner 審查包", + "owner_agent": "openclaw", + "status": "ready_for_owner_review", + "packet_mode": "rollback_owner_review_packet", + "rollback_owner_required": true, + "rollback_owner_confirmed": false, + "rollback_release_passed": false, + "rollback_summary": "整理 Result capture rollback owner review;rollback owner 未 confirmed 前不得通過 rollback release。" + }, + { + "packet_id": "rollback_owner_review_packet_learning", + "display_name": "Learning 回滾 owner 審查包", + "owner_agent": "hermes", + "status": "approval_required", + "packet_mode": "rollback_owner_review_packet", + "rollback_owner_required": true, + "rollback_owner_confirmed": false, + "rollback_release_passed": false, + "rollback_summary": "整理 Learning rollback owner review;rollback owner 未 confirmed 前不得通過 rollback release。" + }, + { + "packet_id": "rollback_owner_review_packet_playbook_trust", + "display_name": "PlayBook trust 回滾 owner 審查包", + "owner_agent": "nemotron", + "status": "blocked_by_policy", + "packet_mode": "rollback_owner_review_packet", + "rollback_owner_required": true, + "rollback_owner_confirmed": false, + "rollback_release_passed": false, + "rollback_summary": "整理 PlayBook trust rollback owner review;rollback owner 未 confirmed 前不得通過 rollback release。" + }, + { + "packet_id": "rollback_owner_review_packet_reviewer_queue", + "display_name": "Reviewer queue 回滾 owner 審查包", + "owner_agent": "openclaw", + "status": "approval_required", + "packet_mode": "rollback_owner_review_packet", + "rollback_owner_required": true, + "rollback_owner_confirmed": false, + "rollback_release_passed": false, + "rollback_summary": "整理 Reviewer queue rollback owner review;rollback owner 未 confirmed 前不得通過 rollback release。" + }, + { + "packet_id": "rollback_owner_review_packet_gateway_queue", + "display_name": "Gateway queue 回滾 owner 審查包", + "owner_agent": "nemotron", + "status": "ready_for_owner_review", + "packet_mode": "rollback_owner_review_packet", + "rollback_owner_required": true, + "rollback_owner_confirmed": false, + "rollback_release_passed": false, + "rollback_summary": "整理 Gateway queue rollback owner review;rollback owner 未 confirmed 前不得通過 rollback release。" + } + ], + "maintenance_window_review_holds": [ + { + "hold_id": "maintenance_window_owner_review_hold_result_capture", + "display_name": "Result capture 維護窗口負責人保留", + "owner_agent": "openclaw", + "status": "ready_for_owner_review", + "hold_mode": "maintenance_window_owner_review_hold", + "owner_release_authorized": false, + "maintenance_window_required": true, + "maintenance_window_approved": false, + "hold_reason": "整理 Result capture maintenance window review;維護窗口未批准前不得 release。" + }, + { + "hold_id": "maintenance_window_owner_review_hold_learning", + "display_name": "Learning 維護窗口負責人保留", + "owner_agent": "hermes", + "status": "approval_required", + "hold_mode": "maintenance_window_owner_review_hold", + "owner_release_authorized": false, + "maintenance_window_required": true, + "maintenance_window_approved": false, + "hold_reason": "整理 Learning maintenance window review;維護窗口未批准前不得 release。" + }, + { + "hold_id": "maintenance_window_owner_review_hold_playbook_trust", + "display_name": "PlayBook trust 維護窗口負責人保留", + "owner_agent": "nemotron", + "status": "blocked_by_policy", + "hold_mode": "maintenance_window_owner_review_hold", + "owner_release_authorized": false, + "maintenance_window_required": true, + "maintenance_window_approved": false, + "hold_reason": "整理 PlayBook trust maintenance window review;維護窗口未批准前不得 release。" + }, + { + "hold_id": "maintenance_window_owner_review_hold_reviewer_queue", + "display_name": "Reviewer queue 維護窗口負責人保留", + "owner_agent": "openclaw", + "status": "approval_required", + "hold_mode": "maintenance_window_owner_review_hold", + "owner_release_authorized": false, + "maintenance_window_required": true, + "maintenance_window_approved": false, + "hold_reason": "整理 Reviewer queue maintenance window review;維護窗口未批准前不得 release。" + }, + { + "hold_id": "maintenance_window_owner_review_hold_gateway_queue", + "display_name": "Gateway queue 維護窗口負責人保留", + "owner_agent": "nemotron", + "status": "ready_for_owner_review", + "hold_mode": "maintenance_window_owner_review_hold", + "owner_release_authorized": false, + "maintenance_window_required": true, + "maintenance_window_approved": false, + "hold_reason": "整理 Gateway queue maintenance window review;維護窗口未批准前不得 release。" + } + ], + "live_apply_owner_review_holds": [ + { + "hold_id": "live_apply_owner_review_hold_result_capture", + "display_name": "Result capture 正式套用負責人保留", + "owner_agent": "openclaw", + "status": "ready_for_owner_review", + "hold_mode": "live_apply_owner_review_hold", + "release_authorization_granted": false, + "release_authorization_passed": false, + "live_apply_release_passed": false, + "live_apply_release_enabled": false, + "release_condition": "整理 Result capture live apply review;release authorization 未核發與通過前不得 live apply。" + }, + { + "hold_id": "live_apply_owner_review_hold_learning", + "display_name": "Learning 正式套用負責人保留", + "owner_agent": "hermes", + "status": "approval_required", + "hold_mode": "live_apply_owner_review_hold", + "release_authorization_granted": false, + "release_authorization_passed": false, + "live_apply_release_passed": false, + "live_apply_release_enabled": false, + "release_condition": "整理 Learning live apply review;release authorization 未核發與通過前不得 live apply。" + }, + { + "hold_id": "live_apply_owner_review_hold_playbook_trust", + "display_name": "PlayBook trust 正式套用負責人保留", + "owner_agent": "nemotron", + "status": "blocked_by_policy", + "hold_mode": "live_apply_owner_review_hold", + "release_authorization_granted": false, + "release_authorization_passed": false, + "live_apply_release_passed": false, + "live_apply_release_enabled": false, + "release_condition": "整理 PlayBook trust live apply review;release authorization 未核發與通過前不得 live apply。" + }, + { + "hold_id": "live_apply_owner_review_hold_reviewer_queue", + "display_name": "Reviewer queue 正式套用負責人保留", + "owner_agent": "openclaw", + "status": "approval_required", + "hold_mode": "live_apply_owner_review_hold", + "release_authorization_granted": false, + "release_authorization_passed": false, + "live_apply_release_passed": false, + "live_apply_release_enabled": false, + "release_condition": "整理 Reviewer queue live apply review;release authorization 未核發與通過前不得 live apply。" + }, + { + "hold_id": "live_apply_owner_review_hold_gateway_queue", + "display_name": "Gateway queue 正式套用負責人保留", + "owner_agent": "nemotron", + "status": "ready_for_owner_review", + "hold_mode": "live_apply_owner_review_hold", + "release_authorization_granted": false, + "release_authorization_passed": false, + "live_apply_release_passed": false, + "live_apply_release_enabled": false, + "release_condition": "整理 Gateway queue live apply review;release authorization 未核發與通過前不得 live apply。" + } + ], + "blocked_owner_review_transitions": [ + { + "transition_id": "owner_review_to_release_authorization", + "status": "blocked_by_policy", + "reason": "owner release authorization 尚未核發,不得轉 release authorization granted。", + "runtime_write_allowed": false + }, + { + "transition_id": "owner_review_to_maintenance_window", + "status": "approval_required", + "reason": "maintenance window 尚未批准,不得轉 release window。", + "runtime_write_allowed": false + }, + { + "transition_id": "owner_review_to_rollback_release", + "status": "blocked_by_policy", + "reason": "rollback owner 尚未確認,不得轉 rollback release。", + "runtime_write_allowed": false + }, + { + "transition_id": "owner_review_to_writer_apply", + "status": "approval_required", + "reason": "writer apply 未授權,不得套用 writer。", + "runtime_write_allowed": false + }, + { + "transition_id": "owner_review_to_gateway_queue", + "status": "blocked_by_policy", + "reason": "Gateway queue write 未授權,不得寫 queue。", + "runtime_write_allowed": false + }, + { + "transition_id": "owner_review_to_telegram_send", + "status": "approval_required", + "reason": "Telegram send 未授權,不得送 Bot API。", + "runtime_write_allowed": false + } + ], + "operator_actions": [ + { + "action_id": "review_owner_packet_scope", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "審查 owner review packet 範圍與 evidence hash;不得核發 release authorization。", + "runtime_write_allowed": false + }, + { + "action_id": "collect_maintenance_window_owner", + "owner_agent": "hermes", + "status": "approval_required", + "operator_instruction": "補維護窗口 owner 與 rollback owner;不得更新 production。", + "runtime_write_allowed": false + }, + { + "action_id": "verify_redaction_boundary", + "owner_agent": "nemotron", + "status": "ready_for_operator_review", + "operator_instruction": "確認前端只顯示 redacted evidence refs,不顯示內部協作內容。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_p2_138_release_decision_hold", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "下一關只可建立 release decision hold,不得 writer apply 或 queue write。", + "runtime_write_allowed": false + }, + { + "action_id": "document_no_live_write_boundary", + "owner_agent": "hermes", + "status": "approval_required", + "operator_instruction": "更新治理文件的 no-live-write 邊界;不得送 Telegram。", + "runtime_write_allowed": false + } + ], + "display_redaction_contract": { + "redaction_required": true, + "raw_prompt_display_allowed": false, + "private_reasoning_display_allowed": false, + "secret_value_display_allowed": false, + "raw_runtime_payload_display_allowed": false, + "internal_collaboration_content_display_allowed": false, + "frontend_display_policy": "只顯示 redacted evidence refs、狀態、owner review packet 與 no-live-write 邊界;不得顯示未審核原始內容、敏感內容或 runtime payload。" + }, + "rollups": { + "owner_review_packet_count": 5, + "verifier_review_packet_count": 5, + "rollback_owner_review_packet_count": 5, + "maintenance_window_review_hold_count": 5, + "live_apply_owner_review_hold_count": 5, + "blocked_owner_review_transition_count": 6, + "operator_action_count": 5, + "approval_required_owner_review_count": 2, + "blocked_owner_review_count": 1, + "approval_required_verifier_review_count": 2, + "blocked_verifier_review_count": 1, + "approval_required_rollback_owner_review_count": 2, + "blocked_rollback_owner_review_count": 1, + "approval_required_maintenance_window_count": 2, + "blocked_maintenance_window_count": 1, + "approval_required_live_apply_review_count": 2, + "blocked_live_apply_review_count": 1, + "critical_blocker_count": 5, + "owner_release_authorized_count": 0, + "owner_release_approved_count": 0, + "owner_review_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "final_release_candidate_approved_count": 0, + "final_release_candidate_pass_count": 0, + "release_authorization_granted_count": 0, + "release_authorization_pass_count": 0, + "rollback_release_pass_count": 0, + "live_apply_release_pass_count": 0, + "writer_apply_count": 0, + "execution_apply_count": 0, + "receipt_write_count": 0, + "reviewer_queue_write_count": 0, + "gateway_queue_write_count": 0, + "telegram_send_count": 0, + "bot_api_call_count": 0, + "report_receipt_write_count": 0, + "result_capture_write_count": 0, + "learning_write_count": 0, + "playbook_trust_write_count": 0, + "production_write_count": 0, + "secret_read_count": 0, + "destructive_operation_count": 0 + } +} diff --git a/docs/schemas/ai_agent_result_capture_release_verifier_owner_review_packet_v1.schema.json b/docs/schemas/ai_agent_result_capture_release_verifier_owner_review_packet_v1.schema.json new file mode 100644 index 000000000..d3d132054 --- /dev/null +++ b/docs/schemas/ai_agent_result_capture_release_verifier_owner_review_packet_v1.schema.json @@ -0,0 +1,109 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://awoooi.wooo.work/schemas/ai_agent_result_capture_release_verifier_owner_review_packet_v1.schema.json", + "title": "AI Agent result capture release verifier owner review packet v1", + "type": "object", + "required": [ + "schema_version", + "generated_at", + "program_status", + "source_refs", + "prior_release_verifier_preflight_gate", + "release_verifier_owner_review_truth", + "owner_review_packets", + "verifier_review_packets", + "rollback_owner_review_packets", + "maintenance_window_review_holds", + "live_apply_owner_review_holds", + "blocked_owner_review_transitions", + "operator_actions", + "display_redaction_contract", + "rollups" + ], + "properties": { + "schema_version": { + "const": "ai_agent_result_capture_release_verifier_owner_review_packet_v1" + }, + "generated_at": { + "type": "string" + }, + "program_status": { + "type": "object" + }, + "source_refs": { + "type": "array", + "items": { + "type": "string" + } + }, + "prior_release_verifier_preflight_gate": { + "type": "object" + }, + "release_verifier_owner_review_truth": { + "type": "object" + }, + "owner_review_packets": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object" + } + }, + "verifier_review_packets": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object" + } + }, + "rollback_owner_review_packets": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object" + } + }, + "maintenance_window_review_holds": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object" + } + }, + "live_apply_owner_review_holds": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object" + } + }, + "blocked_owner_review_transitions": { + "type": "array", + "minItems": 6, + "maxItems": 6, + "items": { + "type": "object" + } + }, + "operator_actions": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object" + } + }, + "display_redaction_contract": { + "type": "object" + }, + "rollups": { + "type": "object" + } + }, + "additionalProperties": false +} diff --git a/docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md b/docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md index 270925a66..2bf6c4040 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 @@ -674,6 +674,7 @@ Alert / Sentry / SigNoz / Gitea / Market Watch / Operator | `docs/evaluations/ai_agent_result_capture_release_authorization_hold_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-authorization-hold` | P2-134 release authorization hold;承接 P2-133 final release candidate readback,建立 5 個 release authorization hold、5 個 rollback authorization hold、5 個 release window hold、5 個 live-apply authorization hold、6 個 blocked authorization transition 與 5 個 operator action;runtime authority 固定 `result_capture_release_authorization_hold_only_no_live_write`;owner release authorized、owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、final release candidate approved、final release candidate passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、canonical runtime target read、live query、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部 `0 / false`;deploy marker `18b867c3` 已正式驗證,下一步 P2-135 | | `docs/evaluations/ai_agent_result_capture_release_authorization_readback_gate_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-authorization-readback-gate` | P2-135 release authorization readback gate;承接 P2-134 release authorization hold,建立 5 個 release authorization readback、5 個 rollback release readback、5 個 maintenance window readback hold、5 個 live-apply release readback hold、6 個 blocked release readback transition 與 5 個 operator action;runtime authority 固定 `result_capture_release_authorization_readback_gate_only_no_live_write`;owner release authorized、owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、final release candidate approved、final release candidate passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、canonical runtime target read、live query、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部 `0 / false`;本地 API / typecheck 已通過,deploy marker `8d575c1a` 已正式驗證,正式 API readback 與 Browser desktop / mobile smoke 已完成 | | `docs/evaluations/ai_agent_result_capture_release_verifier_preflight_gate_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-verifier-preflight-gate` | P2-136 release verifier preflight gate;承接 P2-135 release authorization readback gate,建立 5 個 release verifier preflight、5 個 rollback verifier preflight、5 個 maintenance window verifier hold、5 個 live-apply verifier hold、6 個 blocked verifier preflight transition 與 5 個 operator action;runtime authority 固定 `result_capture_release_verifier_preflight_gate_only_no_live_write`;post-release verifier ready、owner release authorized、owner release approved、maintenance window approved、rollback owner confirmed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、canonical runtime target read、live query、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部 `0 / false`;deploy marker `f2fa8454` 已正式驗證,正式 API readback 與 Browser desktop / mobile smoke 已完成,下一步 P2-137 owner / verifier review packet | +| `docs/evaluations/ai_agent_result_capture_release_verifier_owner_review_packet_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-verifier-owner-review-packet` | P2-137 release verifier owner review packet;承接 P2-136 release verifier preflight gate,建立 5 個 owner review packet、5 個 verifier review packet、5 個 rollback owner review packet、5 個 maintenance window review hold、5 個 live-apply owner review hold、6 個 blocked owner review transition 與 5 個 operator action;runtime authority 固定 `result_capture_release_verifier_owner_review_packet_only_no_live_write`;owner release authorized、owner review approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、canonical runtime target read、live query、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部 `0 / false`;本地 API / typecheck 已通過,正式 deploy 與 production smoke 待補,下一步 P2-138 release decision hold | | `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 主動營運委派與版本生命週期契約 @@ -799,7 +800,8 @@ Repo / registry / release notes / K8s / host / observability / backup evidence 55. 建立 release authorization hold。✅ P2-134 已完成並正式驗證;release authorization hold `5`、rollback authorization hold `5`、release window hold `5`、live-apply authorization hold `5`、blocked authorization transition `6`、operator action `5`,approval-required authorization / rollback / release window / live apply `2 / 2 / 2 / 2`、blocked authorization / rollback / release window / live apply `1 / 1 / 1 / 1`、critical blocker `5`;owner release authorized、owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、final release candidate approved、final release candidate passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write 仍為 `0 / false`;deploy marker `18b867c3`、正式 API readback 與 desktop / mobile smoke 已完成。下一步 P2-135。 56. 建立 release authorization readback gate。✅ P2-135 已完成並正式驗證;release authorization readback `5`、rollback release readback `5`、maintenance window readback hold `5`、live-apply release readback hold `5`、blocked release readback transition `6`、operator action `5`,approval-required readback / rollback / maintenance / live apply `2 / 2 / 2 / 2`、blocked readback / rollback / maintenance / live apply `1 / 1 / 1 / 1`、critical blocker `5`;owner release authorized、owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、final release candidate approved、final release candidate passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write 仍為 `0 / false`;deploy marker `8d575c1a`、正式 API readback 與 desktop / mobile smoke 已完成。已由 P2-136 承接。 57. 建立 release verifier preflight gate。✅ P2-136 已完成並正式驗證;release verifier preflight `5`、rollback verifier preflight `5`、maintenance window verifier hold `5`、live-apply verifier hold `5`、blocked verifier preflight transition `6`、operator action `5`,approval-required preflight / rollback / maintenance / live apply `2 / 2 / 2 / 2`、blocked preflight / rollback / maintenance / live apply `1 / 1 / 1 / 1`、critical blocker `5`,前端顯示阻擋總數 `9`;post-release verifier ready、owner release authorized、owner release approved、maintenance window approved、rollback owner confirmed、final release candidate approved、final release candidate passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 仍為 `0 / false`;deploy marker `f2fa8454`、正式 API readback 與 desktop / mobile smoke 已完成。已由 P2-137 承接。 -58. 建立 owner / verifier review packet。⬜ P2-137 planned;承接 P2-136,只能整理 owner / verifier / rollback / maintenance window / live-apply review packet 的只讀證據,不得把 review packet 視為授權通過,不得寫 reviewer queue、Gateway queue、Telegram、Bot API、result capture、learning、PlayBook trust 或 production target。 +58. 建立 owner / verifier review packet。✅ P2-137 已本地完成;owner review packet `5`、verifier review packet `5`、rollback owner review packet `5`、maintenance window review hold `5`、live-apply owner review hold `5`、blocked owner review transition `6`、operator action `5`,approval-required owner / verifier / rollback / maintenance / live apply `2 / 2 / 2 / 2 / 2`、blocked owner / verifier / rollback / maintenance / live apply `1 / 1 / 1 / 1 / 1`、critical blocker `5`;owner release authorized、owner review approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 仍為 `0 / false`;本地 API/service pytest `7 passed`、JSON parse、Python compile、Web typecheck 通過。正式 deploy 與 production smoke 待補。 +59. 建立 release decision hold。⬜ P2-138 planned;承接 P2-137,只能整理 release decision hold 的只讀證據,不得把 owner review packet 視為授權通過,不得寫 reviewer queue、Gateway queue、Telegram、Bot API、result capture、learning、PlayBook trust 或 production target。 #### 3.2.1d 2026-06-11 Agent 互動、學習與成長證據面 @@ -1926,6 +1928,13 @@ Phase 6 完成後 - `a3de0ffb` AI Agent 活動動畫已由 deploy marker `60a0415c chore(cd): deploy a3de0ff [skip ci]` 正式部署;`automation-inventory` 與 `agent-market` desktop / mobile smoke 均確認動畫元件可見、水平溢位 `0`、危險控制 `0`、console error `0`、禁用內部協作片語命中 `0`。 - 本波仍不讀 canonical runtime target、不做 live query、不寫 reviewer queue、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不寫 result capture、不寫 learning、不更新 PlayBook trust、不寫 production target、不讀 secret、不執行 destructive action、不回傳內部協作內容;已由 P2-137 planned 承接。 +### 2026-06-14 10:12 (台北) — §3.2 / §5 — 新增 P2-137 release verifier owner review packet — 本地完成負責人審查包只讀關卡 + +- 新增 `ai_agent_result_capture_release_verifier_owner_review_packet_v1` schema、snapshot、loader、API route、governance UI 與繁中訊息;承接 P2-136 release verifier preflight gate,但不把 preflight 或 review packet 解讀成 owner release authorized、release authorization granted / passed、post-release verifier ready 或 live apply release passed。 +- 本地 rollup:owner review packet `5`、verifier review packet `5`、rollback owner review packet `5`、maintenance window review hold `5`、live-apply owner review hold `5`、blocked owner review transition `6`、operator action `5`、需批准 `10`、阻擋 `10`、正式寫入 / 發送 `0`。 +- 本地驗證:JSON parse、Python compile、P2-137 API/service pytest `7 passed`、Web typecheck 通過。 +- 本波仍不讀 canonical runtime target、不做 live query、不寫 reviewer queue、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不寫 result capture、不寫 learning、不更新 PlayBook trust、不寫 production target、不讀 secret、不執行 destructive action、不回傳內部工作內容;正式驗證後才可由 P2-138 release decision hold 承接。 + ### 2026-06-14 08:36 (台北) — §3.2 / §5 — 正式驗證 P2-134 release authorization hold — 完成釋出授權保留只讀關卡 - Feature commit `e0a6d339` 已由 deploy marker `18b867c3 chore(cd): deploy e0a6d33 [skip ci]` 部署;正式 API health 回 `healthy`、`environment=prod`、`mock_mode=false`。