From 040c320c5ecf328035eaa35de86a7b76b9c4e651 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 14 Jun 2026 05:33:48 +0800 Subject: [PATCH] =?UTF-8?q?feat(governance):=20=E6=96=B0=E5=A2=9E=20post-r?= =?UTF-8?q?elease=20verifier=20rollback=20gate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api/src/api/v1/agents.py | 34 ++ ...ure_post_release_verifier_rollback_gate.py | 408 +++++++++++++++ ...ure_post_release_verifier_rollback_gate.py | 109 ++++ ...post_release_verifier_rollback_gate_api.py | 47 ++ apps/web/messages/en.json | 34 ++ apps/web/messages/zh-TW.json | 34 ++ .../tabs/automation-inventory-tab.tsx | 188 ++++++- apps/web/src/lib/api-client.ts | 211 ++++++++ docs/LOGBOOK.md | 25 + ...AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md | 8 +- ...ase_verifier_rollback_gate_2026-06-14.json | 470 ++++++++++++++++++ ...ease_verifier_rollback_gate_v1.schema.json | 100 ++++ ...-04-15-MASTER-ai-autonomous-flywheel-v2.md | 14 +- 13 files changed, 1676 insertions(+), 6 deletions(-) create mode 100644 apps/api/src/services/ai_agent_result_capture_post_release_verifier_rollback_gate.py create mode 100644 apps/api/tests/test_ai_agent_result_capture_post_release_verifier_rollback_gate.py create mode 100644 apps/api/tests/test_ai_agent_result_capture_post_release_verifier_rollback_gate_api.py create mode 100644 docs/evaluations/ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json create mode 100644 docs/schemas/ai_agent_result_capture_post_release_verifier_rollback_gate_v1.schema.json diff --git a/apps/api/src/api/v1/agents.py b/apps/api/src/api/v1/agents.py index 9b6d3403d..6103fcbb4 100644 --- a/apps/api/src/api/v1/agents.py +++ b/apps/api/src/api/v1/agents.py @@ -142,6 +142,9 @@ from src.services.ai_agent_result_capture_owner_approved_release_readiness_readb from src.services.ai_agent_result_capture_owner_release_approval_gate import ( load_latest_ai_agent_result_capture_owner_release_approval_gate, ) +from src.services.ai_agent_result_capture_post_release_verifier_rollback_gate import ( + load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate, +) from src.services.ai_agent_result_capture_promotion_approval_gate import ( load_latest_ai_agent_result_capture_promotion_approval_gate, ) @@ -2051,6 +2054,37 @@ async def get_agent_result_capture_owner_release_approval_gate() -> dict[str, An ) from exc +@router.get( + "/agent-result-capture-post-release-verifier-rollback-gate", + response_model=dict[str, Any], + summary="取得 AI Agent result capture post-release verifier rollback gate", + description=( + "讀取最新已提交的 P2-132 post-release verifier / rollback gate;" + "此端點只回傳 post-release verifier gate、rollback release gate、release verification hold、" + "live apply post-release gate、blocked post-release transition 與 operator handoff," + "不批准 owner release、不批准 maintenance window、不確認 rollback owner、不釋放 live apply、" + "不套用 writer、不寫 receipt、不寫 result capture、learning、PlayBook trust、reviewer queue、" + "Gateway queue,不送 Telegram、不呼叫 Bot API、不讀 secret。" + ), +) +async def get_agent_result_capture_post_release_verifier_rollback_gate() -> dict[str, Any]: + """Return the latest read-only post-release verifier / rollback gate.""" + try: + payload = await asyncio.to_thread(load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate) + 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_post_release_verifier_rollback_gate_invalid", error=str(exc)) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="AI Agent result capture post-release verifier rollback gate 無效", + ) 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_post_release_verifier_rollback_gate.py b/apps/api/src/services/ai_agent_result_capture_post_release_verifier_rollback_gate.py new file mode 100644 index 000000000..a603163f6 --- /dev/null +++ b/apps/api/src/services/ai_agent_result_capture_post_release_verifier_rollback_gate.py @@ -0,0 +1,408 @@ +""" +AI Agent result capture post-release verifier rollback gate snapshot. + +Loads the latest committed P2-132 post-release verifier / rollback gate. +This module validates committed evidence only; it never approves owner release, +approves maintenance windows, confirms rollback owners, 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 +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_post_release_verifier_rollback_gate_*.json" +_SCHEMA_VERSION = "ai_agent_result_capture_post_release_verifier_rollback_gate_v1" +_RUNTIME_AUTHORITY = "result_capture_post_release_verifier_rollback_gate_only_no_live_write" + + +def load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate( + evaluations_dir: Path | None = None, +) -> dict[str, Any]: + """Load the newest committed post-release verifier / rollback gate.""" + directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR + candidates = sorted(directory.glob(_SNAPSHOT_PATTERN)) + if not candidates: + raise FileNotFoundError(f"no AI Agent result capture post-release verifier rollback gate 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_verifier_gates(payload, label) + _require_rollback_gates(payload, label) + _require_verification_holds(payload, label) + _require_live_apply_gates(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-132", + "next_task_id": "P2-133", + "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_owner_release_approval_gate") or {} + expected = { + "schema_version": "ai_agent_result_capture_owner_release_approval_gate_v1", + "owner_release_approval_packet_count": 5, + "maintenance_window_approval_gate_count": 5, + "live_apply_release_approval_gate_count": 5, + "rollback_owner_approval_check_count": 5, + "blocked_approval_transition_count": 6, + "operator_action_count": 5, + "approval_required_total": 8, + "blocked_total": 9, + "owner_release_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "release_approval_pass_count": 0, + "live_apply_release_pass_count": 0, + "writer_apply_count": 0, + "execution_apply_count": 0, + "receipt_write_count": 0, + "result_capture_write_count": 0, + "learning_write_count": 0, + "playbook_trust_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, + } + mismatches = _mismatches(prior, expected) + if mismatches: + raise ValueError(f"{label}: prior_owner_release_approval_gate mismatch: {mismatches}") + if not prior.get("readiness_note"): + raise ValueError(f"{label}: prior_owner_release_approval_gate.readiness_note is required") + + +def _require_truth(payload: dict[str, Any], label: str) -> None: + truth = payload.get("post_release_verifier_truth") or {} + required_true = { + "p2_131_approval_gate_loaded", + "post_release_verifier_gate_ready", + "rollback_release_gate_ready", + "release_verification_hold_active", + "live_apply_post_release_hold_active", + "owner_release_review_still_required", + "maintenance_window_review_still_required", + "rollback_owner_review_required", + "redaction_review_required", + "post_release_verifier_gate_only", + } + missing = sorted(field for field in required_true if truth.get(field) is not True) + if missing: + raise ValueError(f"{label}: post-release verifier gate flags must remain true: {missing}") + + required_false = { + "owner_release_approved", + "maintenance_window_approved", + "rollback_owner_confirmed", + "post_release_verifier_ready", + "release_verification_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}: post-release verifier live/send/write flags must remain false: {unsafe}") + + zero_counts = { + "owner_release_approved_count", + "maintenance_window_approved_count", + "rollback_owner_confirmed_count", + "post_release_verifier_ready_count", + "release_verification_pass_count", + "rollback_release_pass_count", + "live_apply_release_pass_count", + "writer_apply_count", + "execution_apply_count", + "receipt_write_count", + "reviewer_queue_write_count", + "gateway_queue_write_count", + "telegram_send_count", + "bot_api_call_count", + "report_receipt_write_count", + "result_capture_write_count", + "learning_write_count", + "playbook_trust_write_count", + "production_write_count", + "secret_read_count", + "destructive_operation_count", + } + non_zero = sorted(field for field in zero_counts if truth.get(field) != 0) + if non_zero: + raise ValueError(f"{label}: post-release verifier live counters must remain zero: {non_zero}") + if not truth.get("truth_note"): + raise ValueError(f"{label}: post_release_verifier_truth.truth_note is required") + + +def _require_verifier_gates(payload: dict[str, Any], label: str) -> None: + items = payload.get("post_release_verifier_gates") or [] + _require_ids( + items, + "gate_id", + { + "post_release_verifier_result_capture", + "post_release_verifier_learning", + "post_release_verifier_playbook_trust", + "post_release_verifier_reviewer_queue", + "post_release_verifier_gateway_queue", + }, + label, + "post-release verifier gates", + ) + for item in items: + item_id = item.get("gate_id") + if item.get("gate_mode") != "post_release_verifier_gate": + raise ValueError(f"{label}: post-release verifier gate {item_id} mode is invalid") + if item.get("post_release_verifier_ready") is not False or item.get("release_verification_passed") is not False: + raise ValueError(f"{label}: post-release verifier gate {item_id} must stay unready and unpassed") + if item.get("status") not in {"ready_for_owner_review", "approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: post-release verifier gate {item_id} status is invalid") + if not item.get("verifier_summary") or not _is_redacted_sha256(item.get("evidence_hash")): + raise ValueError(f"{label}: post-release verifier gate {item_id} must include summary and redacted evidence_hash") + + +def _require_rollback_gates(payload: dict[str, Any], label: str) -> None: + items = payload.get("rollback_release_gates") or [] + _require_count(items, 5, label, "rollback release gates") + for item in items: + item_id = item.get("gate_id") + if item.get("gate_mode") != "rollback_release_gate": + raise ValueError(f"{label}: rollback release gate {item_id} mode is invalid") + if item.get("rollback_owner_required") is not True: + raise ValueError(f"{label}: rollback release gate {item_id} must require rollback owner") + if item.get("rollback_owner_confirmed") is not False or item.get("rollback_release_enabled") is not False: + raise ValueError(f"{label}: rollback release gate {item_id} must stay unconfirmed and disabled") + if item.get("status") not in {"ready_for_owner_review", "approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: rollback release gate {item_id} status is invalid") + + +def _require_verification_holds(payload: dict[str, Any], label: str) -> None: + items = payload.get("release_verification_holds") or [] + _require_count(items, 5, label, "release verification holds") + for item in items: + item_id = item.get("hold_id") + if item.get("hold_mode") != "release_verification_hold": + raise ValueError(f"{label}: release verification hold {item_id} mode is invalid") + if item.get("owner_release_approved") is not False or item.get("maintenance_window_approved") is not False: + raise ValueError(f"{label}: release verification hold {item_id} must stay unapproved") + if item.get("release_verification_passed") is not False: + raise ValueError(f"{label}: release verification hold {item_id} must stay unpassed") + if item.get("status") not in {"ready_for_owner_review", "approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: release verification hold {item_id} status is invalid") + + +def _require_live_apply_gates(payload: dict[str, Any], label: str) -> None: + items = payload.get("live_apply_post_release_gates") or [] + _require_count(items, 5, label, "live apply post-release gates") + for item in items: + item_id = item.get("gate_id") + if item.get("gate_mode") != "live_apply_post_release_gate": + raise ValueError(f"{label}: live apply post-release gate {item_id} mode is invalid") + if item.get("post_release_verifier_ready") is not False or item.get("live_apply_release_enabled") is not False: + raise ValueError(f"{label}: live apply post-release gate {item_id} must stay held and disabled") + if item.get("status") not in {"ready_for_owner_review", "approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: live apply post-release gate {item_id} status is invalid") + + +def _require_blocked_transitions(payload: dict[str, Any], label: str) -> None: + items = payload.get("blocked_post_release_transitions") or [] + _require_count(items, 6, label, "blocked post-release transitions") + critical = 0 + for item in items: + item_id = item.get("blocker_id") + if item.get("status") not in {"approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: blocked post-release transition {item_id} status is invalid") + if item.get("severity") == "critical": + critical += 1 + if not item.get("blocked_action") or not _is_redacted_sha256(item.get("evidence_hash")): + raise ValueError(f"{label}: blocked post-release transition {item_id} must include action and redacted evidence_hash") + if critical != 5: + raise ValueError(f"{label}: expected 5 critical blocked post-release transitions, got {critical}") + + +def _require_actions(payload: dict[str, Any], label: str) -> None: + items = payload.get("operator_actions") or [] + _require_ids( + items, + "action_id", + { + "review_post_release_verifier_gates", + "verify_rollback_release_gate", + "verify_release_verification_hold", + "verify_live_apply_post_release_hold", + "prepare_p2_133_final_release_candidate_readback", + }, + label, + "operator actions", + ) + for item in items: + if item.get("runtime_write_allowed") is not False: + raise ValueError(f"{label}: operator action {item.get('action_id')} must keep runtime_write_allowed=false") + if item.get("status") not in {"ready_for_operator_review", "approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: operator action {item.get('action_id')} status is invalid") + + +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_no_forbidden_display_terms(payload: dict[str, Any], label: str) -> None: + forbidden = { + "work_window_transcript", + "session_id", + "browser_context", + "authorization_header", + "raw Telegram payload", + "private reasoning", + "raw prompt", + "chain-of-thought", + "批准!繼續", + "My request for Codex", + "In app browser", + } + text = json.dumps(payload, ensure_ascii=False) + present = sorted(term for term in forbidden if term in text) + if present: + raise ValueError(f"{label}: forbidden display terms present: {present}") + + +def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None: + rollups = payload.get("rollups") or {} + expected = { + "post_release_verifier_gate_count": len(payload.get("post_release_verifier_gates") or []), + "rollback_release_gate_count": len(payload.get("rollback_release_gates") or []), + "release_verification_hold_count": len(payload.get("release_verification_holds") or []), + "live_apply_post_release_gate_count": len(payload.get("live_apply_post_release_gates") or []), + "blocked_post_release_transition_count": len(payload.get("blocked_post_release_transitions") or []), + "operator_action_count": len(payload.get("operator_actions") or []), + "approval_required_verifier_count": _count_status(payload.get("post_release_verifier_gates"), "approval_required"), + "blocked_verifier_count": _count_status(payload.get("post_release_verifier_gates"), "blocked_by_policy"), + "approval_required_rollback_count": _count_status(payload.get("rollback_release_gates"), "approval_required"), + "blocked_rollback_count": _count_status(payload.get("rollback_release_gates"), "blocked_by_policy"), + "approval_required_verification_hold_count": _count_status(payload.get("release_verification_holds"), "approval_required"), + "blocked_verification_hold_count": _count_status(payload.get("release_verification_holds"), "blocked_by_policy"), + "approval_required_live_apply_count": _count_status(payload.get("live_apply_post_release_gates"), "approval_required"), + "blocked_live_apply_count": _count_status(payload.get("live_apply_post_release_gates"), "blocked_by_policy"), + "critical_blocker_count": sum(1 for item in payload.get("blocked_post_release_transitions") or [] if item.get("severity") == "critical"), + } + zero_fields = { + "owner_release_approved_count", + "maintenance_window_approved_count", + "rollback_owner_confirmed_count", + "post_release_verifier_ready_count", + "release_verification_pass_count", + "rollback_release_pass_count", + "live_apply_release_pass_count", + "writer_apply_count", + "execution_apply_count", + "receipt_write_count", + "reviewer_queue_write_count", + "gateway_queue_write_count", + "telegram_send_count", + "bot_api_call_count", + "report_receipt_write_count", + "result_capture_write_count", + "learning_write_count", + "playbook_trust_write_count", + "production_write_count", + "secret_read_count", + "destructive_operation_count", + } + expected.update({field: 0 for field in zero_fields}) + mismatches = _mismatches(rollups, expected) + if mismatches: + raise ValueError(f"{label}: rollup counts mismatch: {mismatches}") + + +def _mismatches(source: dict[str, Any], expected: dict[str, Any]) -> dict[str, dict[str, Any]]: + return {key: {"expected": value, "actual": source.get(key)} for key, value in expected.items() if source.get(key) != value} + + +def _require_count(items: Any, expected_count: int, label: str, name: str) -> None: + if not isinstance(items, list) or len(items) != expected_count: + raise ValueError(f"{label}: expected {expected_count} {name}, got {len(items) if isinstance(items, list) else 'non-list'}") + + +def _require_ids(items: list[dict[str, Any]], id_field: str, expected_ids: set[str], label: str, name: str) -> None: + _require_count(items, len(expected_ids), label, name) + found = {str(item.get(id_field)) for item in items} + if found != expected_ids: + raise ValueError(f"{label}: {name} ids mismatch: expected={sorted(expected_ids)} actual={sorted(found)}") + + +def _count_status(items: Any, status: str) -> int: + if not isinstance(items, list): + return 0 + return sum(1 for item in items if isinstance(item, dict) and item.get("status") == status) + + +def _is_redacted_sha256(value: Any) -> bool: + if not isinstance(value, str): + return False + prefix = "sha256:" + return value.startswith(prefix) and len(value) == len(prefix) + 64 diff --git a/apps/api/tests/test_ai_agent_result_capture_post_release_verifier_rollback_gate.py b/apps/api/tests/test_ai_agent_result_capture_post_release_verifier_rollback_gate.py new file mode 100644 index 000000000..5414a8ee7 --- /dev/null +++ b/apps/api/tests/test_ai_agent_result_capture_post_release_verifier_rollback_gate.py @@ -0,0 +1,109 @@ +from __future__ import annotations + +import json +from pathlib import Path + +import pytest + +from src.services.ai_agent_result_capture_post_release_verifier_rollback_gate import ( + load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate, +) + +REPO_ROOT = Path(__file__).resolve().parents[3] +FIXTURE = REPO_ROOT / "docs/evaluations/ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json" + + +def test_load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate_snapshot() -> None: + data = load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate() + + assert data["schema_version"] == "ai_agent_result_capture_post_release_verifier_rollback_gate_v1" + assert data["program_status"]["current_task_id"] == "P2-132" + assert data["program_status"]["next_task_id"] == "P2-133" + assert data["program_status"]["runtime_authority"] == "result_capture_post_release_verifier_rollback_gate_only_no_live_write" + + rollups = data["rollups"] + assert rollups["post_release_verifier_gate_count"] == 5 + assert rollups["rollback_release_gate_count"] == 5 + assert rollups["release_verification_hold_count"] == 5 + assert rollups["live_apply_post_release_gate_count"] == 5 + assert rollups["blocked_post_release_transition_count"] == 6 + assert rollups["operator_action_count"] == 5 + assert rollups["critical_blocker_count"] == 5 + assert rollups["owner_release_approved_count"] == 0 + assert rollups["maintenance_window_approved_count"] == 0 + assert rollups["rollback_owner_confirmed_count"] == 0 + assert rollups["post_release_verifier_ready_count"] == 0 + assert rollups["release_verification_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["gateway_queue_write_count"] == 0 + assert rollups["telegram_send_count"] == 0 + assert rollups["bot_api_call_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 + assert {item["post_release_verifier_ready"] for item in data["post_release_verifier_gates"]} == {False} + assert {item["rollback_release_enabled"] for item in data["rollback_release_gates"]} == {False} + assert {item["release_verification_passed"] for item in data["release_verification_holds"]} == {False} + assert {item["live_apply_release_enabled"] for item in data["live_apply_post_release_gates"]} == {False} + + +def _copy_fixture(tmp_path: Path) -> dict: + source = json.loads(FIXTURE.read_text(encoding="utf-8")) + target = tmp_path / "ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json" + target.write_text(json.dumps(source, ensure_ascii=False), encoding="utf-8") + return source + + +def test_result_capture_post_release_verifier_gate_rejects_verifier_ready(tmp_path: Path) -> None: + source = _copy_fixture(tmp_path) + source["post_release_verifier_gates"][0]["post_release_verifier_ready"] = True + target = tmp_path / "ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json" + target.write_text(json.dumps(source, ensure_ascii=False), encoding="utf-8") + + with pytest.raises(ValueError, match="must stay unready and unpassed"): + load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate(tmp_path) + + +def test_result_capture_post_release_verifier_gate_rejects_rollback_enabled(tmp_path: Path) -> None: + source = _copy_fixture(tmp_path) + source["rollback_release_gates"][0]["rollback_release_enabled"] = True + target = tmp_path / "ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json" + target.write_text(json.dumps(source, ensure_ascii=False), encoding="utf-8") + + with pytest.raises(ValueError, match="must stay unconfirmed and disabled"): + load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate(tmp_path) + + +def test_result_capture_post_release_verifier_gate_rejects_live_apply_enabled(tmp_path: Path) -> None: + source = _copy_fixture(tmp_path) + source["live_apply_post_release_gates"][0]["live_apply_release_enabled"] = True + target = tmp_path / "ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json" + target.write_text(json.dumps(source, ensure_ascii=False), encoding="utf-8") + + with pytest.raises(ValueError, match="must stay held and disabled"): + load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate(tmp_path) + + +def test_result_capture_post_release_verifier_gate_rejects_rollup_drift(tmp_path: Path) -> None: + source = _copy_fixture(tmp_path) + source["rollups"]["post_release_verifier_gate_count"] = 4 + target = tmp_path / "ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json" + target.write_text(json.dumps(source, ensure_ascii=False), encoding="utf-8") + + with pytest.raises(ValueError, match="rollup counts mismatch"): + load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate(tmp_path) + + +def test_result_capture_post_release_verifier_gate_rejects_forbidden_display_terms(tmp_path: Path) -> None: + source = _copy_fixture(tmp_path) + source["operator_actions"][0]["operator_instruction"] = "work_window_transcript must never show" + target = tmp_path / "ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json" + target.write_text(json.dumps(source, ensure_ascii=False), encoding="utf-8") + + with pytest.raises(ValueError, match="forbidden display terms"): + load_latest_ai_agent_result_capture_post_release_verifier_rollback_gate(tmp_path) diff --git a/apps/api/tests/test_ai_agent_result_capture_post_release_verifier_rollback_gate_api.py b/apps/api/tests/test_ai_agent_result_capture_post_release_verifier_rollback_gate_api.py new file mode 100644 index 000000000..c55d83786 --- /dev/null +++ b/apps/api/tests/test_ai_agent_result_capture_post_release_verifier_rollback_gate_api.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +import pytest +from httpx import ASGITransport, AsyncClient + +from src.main import app + + +@pytest.mark.asyncio +async def test_get_agent_result_capture_post_release_verifier_rollback_gate_api() -> None: + transport = ASGITransport(app=app) + async with AsyncClient(transport=transport, base_url="http://testserver") as client: + response = await client.get("/api/v1/agents/agent-result-capture-post-release-verifier-rollback-gate") + + assert response.status_code == 200 + data = response.json() + assert data["schema_version"] == "ai_agent_result_capture_post_release_verifier_rollback_gate_v1" + assert data["program_status"]["current_task_id"] == "P2-132" + assert data["program_status"]["next_task_id"] == "P2-133" + + rollups = data["rollups"] + assert rollups["post_release_verifier_gate_count"] == 5 + assert rollups["rollback_release_gate_count"] == 5 + assert rollups["release_verification_hold_count"] == 5 + assert rollups["live_apply_post_release_gate_count"] == 5 + assert rollups["blocked_post_release_transition_count"] == 6 + assert rollups["operator_action_count"] == 5 + assert rollups["owner_release_approved_count"] == 0 + assert rollups["maintenance_window_approved_count"] == 0 + assert rollups["rollback_owner_confirmed_count"] == 0 + assert rollups["post_release_verifier_ready_count"] == 0 + assert rollups["release_verification_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["result_capture_write_count"] == 0 + assert rollups["learning_write_count"] == 0 + assert rollups["playbook_trust_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["production_write_count"] == 0 + assert {item["post_release_verifier_ready"] for item in data["post_release_verifier_gates"]} == {False} + assert {item["rollback_release_enabled"] for item in data["rollback_release_gates"]} == {False} + assert {item["live_apply_release_enabled"] for item in data["live_apply_post_release_gates"]} == {False} diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 6196ce792..f600bf01a 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -5976,6 +5976,40 @@ "rollbackPassed": "rollback readiness passed={value}" } }, + "resultCapturePostReleaseVerifierRollbackGate": { + "title": "P2-132 post-release verifier / rollback gate", + "source": "產生 {generated};目前 {current};下一步 {next}", + "priorTitle": "前一關 owner release approval", + "truthTitle": "post-release verifier 真相", + "metrics": { + "overall": "完成度", + "verifiers": "Verifier gates", + "rollbackGates": "Rollback gates", + "verificationHolds": "Verification holds", + "liveApplyGates": "Live-apply post gates", + "blockers": "已阻擋 post-release", + "actions": "操作選項", + "approvalRequired": "需批准", + "blocked": "阻擋", + "liveWrites": "正式寫入 / 發送" + }, + "flags": { + "p2Loaded": "已載入 P2-131={value}", + "verifierReady": "post-release verifier gate ready={value}", + "liveApplyHoldActive": "live apply post-release hold active={value}" + }, + "labels": { + "ownerReleaseApproved": "owner release approved={value}", + "verificationPassed": "release verification passed={value}", + "gatewayWrites": "Gateway 寫入={value}", + "postReleaseVerifierReady": "post-release verifier ready={value}", + "rollbackRequired": "需要 rollback owner={value}", + "rollbackConfirmed": "rollback owner confirmed={value}", + "rollbackEnabled": "rollback release enabled={value}", + "liveApplyReleaseEnabled": "live apply release enabled={value}", + "runtimeWriteAllowed": "runtime write allowed={value}" + } + }, "resultCaptureOwnerReleaseApprovalGate": { "title": "P2-131 owner release approval gate", "source": "產生 {generated};目前 {current};下一步 {next}", diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 6196ce792..f600bf01a 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -5976,6 +5976,40 @@ "rollbackPassed": "rollback readiness passed={value}" } }, + "resultCapturePostReleaseVerifierRollbackGate": { + "title": "P2-132 post-release verifier / rollback gate", + "source": "產生 {generated};目前 {current};下一步 {next}", + "priorTitle": "前一關 owner release approval", + "truthTitle": "post-release verifier 真相", + "metrics": { + "overall": "完成度", + "verifiers": "Verifier gates", + "rollbackGates": "Rollback gates", + "verificationHolds": "Verification holds", + "liveApplyGates": "Live-apply post gates", + "blockers": "已阻擋 post-release", + "actions": "操作選項", + "approvalRequired": "需批准", + "blocked": "阻擋", + "liveWrites": "正式寫入 / 發送" + }, + "flags": { + "p2Loaded": "已載入 P2-131={value}", + "verifierReady": "post-release verifier gate ready={value}", + "liveApplyHoldActive": "live apply post-release hold active={value}" + }, + "labels": { + "ownerReleaseApproved": "owner release approved={value}", + "verificationPassed": "release verification passed={value}", + "gatewayWrites": "Gateway 寫入={value}", + "postReleaseVerifierReady": "post-release verifier ready={value}", + "rollbackRequired": "需要 rollback owner={value}", + "rollbackConfirmed": "rollback owner confirmed={value}", + "rollbackEnabled": "rollback release enabled={value}", + "liveApplyReleaseEnabled": "live apply release enabled={value}", + "runtimeWriteAllowed": "runtime write allowed={value}" + } + }, "resultCaptureOwnerReleaseApprovalGate": { "title": "P2-131 owner release approval gate", "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 c410e1360..a3a5e3a71 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 @@ -79,6 +79,7 @@ import { type AiAgentResultCaptureOwnerApprovedPreflightReleasePackageSnapshot, type AiAgentResultCaptureOwnerApprovedReleaseReadinessReadbackSnapshot, type AiAgentResultCaptureOwnerReleaseApprovalGateSnapshot, + type AiAgentResultCapturePostReleaseVerifierRollbackGateSnapshot, type AiAgentResultCaptureWriterImplementationReviewSnapshot, type AiAgentOwnerApprovedFixturePromotionGateSnapshot, type AiAgentRuntimeWorkerShadowGateSnapshot, @@ -481,6 +482,7 @@ export function AutomationInventoryTab() { const [resultCaptureOwnerApprovedPreflightReleasePackage, setResultCaptureOwnerApprovedPreflightReleasePackage] = useState(null) const [resultCaptureOwnerApprovedReleaseReadinessReadback, setResultCaptureOwnerApprovedReleaseReadinessReadback] = useState(null) const [resultCaptureOwnerReleaseApprovalGate, setResultCaptureOwnerReleaseApprovalGate] = useState(null) + const [resultCapturePostReleaseVerifierRollbackGate, setResultCapturePostReleaseVerifierRollbackGate] = useState(null) const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState(null) const [ownerDryRunPackage, setOwnerDryRunPackage] = useState(null) const [hostStatefulInventory, setHostStatefulInventory] = useState(null) @@ -549,6 +551,7 @@ export function AutomationInventoryTab() { apiClient.getAiAgentResultCaptureOwnerApprovedPreflightReleasePackage(), apiClient.getAiAgentResultCaptureOwnerApprovedReleaseReadinessReadback(), apiClient.getAiAgentResultCaptureOwnerReleaseApprovalGate(), + apiClient.getAiAgentResultCapturePostReleaseVerifierRollbackGate(), apiClient.getAiAgentReportTruthActionabilityReview(), apiClient.getAiAgentOwnerApprovedFixtureDryRun(), apiClient.getAiAgentHostStatefulVersionInventory(), @@ -616,6 +619,7 @@ export function AutomationInventoryTab() { resultCaptureOwnerApprovedPreflightReleasePackageResult, resultCaptureOwnerApprovedReleaseReadinessReadbackResult, resultCaptureOwnerReleaseApprovalGateResult, + resultCapturePostReleaseVerifierRollbackGateResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -680,6 +684,7 @@ export function AutomationInventoryTab() { setResultCaptureOwnerApprovedPreflightReleasePackage(resultCaptureOwnerApprovedPreflightReleasePackageResult.status === 'fulfilled' ? resultCaptureOwnerApprovedPreflightReleasePackageResult.value : null) setResultCaptureOwnerApprovedReleaseReadinessReadback(resultCaptureOwnerApprovedReleaseReadinessReadbackResult.status === 'fulfilled' ? resultCaptureOwnerApprovedReleaseReadinessReadbackResult.value : null) setResultCaptureOwnerReleaseApprovalGate(resultCaptureOwnerReleaseApprovalGateResult.status === 'fulfilled' ? resultCaptureOwnerReleaseApprovalGateResult.value : null) + setResultCapturePostReleaseVerifierRollbackGate(resultCapturePostReleaseVerifierRollbackGateResult.status === 'fulfilled' ? resultCapturePostReleaseVerifierRollbackGateResult.value : null) setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null) setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null) setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null) @@ -742,6 +747,7 @@ export function AutomationInventoryTab() { resultCaptureOwnerApprovedPreflightReleasePackageResult, resultCaptureOwnerApprovedReleaseReadinessReadbackResult, resultCaptureOwnerReleaseApprovalGateResult, + resultCapturePostReleaseVerifierRollbackGateResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -1984,7 +1990,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 || !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 || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { return (
@@ -3062,6 +3068,40 @@ export function AutomationInventoryTab() { + resultCaptureOwnerReleaseApprovalGate.rollups.playbook_trust_write_count + resultCaptureOwnerReleaseApprovalGate.rollups.production_write_count ) + const resultCapturePostReleaseVerifierOverall = resultCapturePostReleaseVerifierRollbackGate.program_status.overall_completion_percent + const resultCapturePostReleaseVerifierGates = resultCapturePostReleaseVerifierRollbackGate.rollups.post_release_verifier_gate_count + const resultCapturePostReleaseRollbackGates = resultCapturePostReleaseVerifierRollbackGate.rollups.rollback_release_gate_count + const resultCapturePostReleaseVerificationHolds = resultCapturePostReleaseVerifierRollbackGate.rollups.release_verification_hold_count + const resultCapturePostReleaseLiveApplyGates = resultCapturePostReleaseVerifierRollbackGate.rollups.live_apply_post_release_gate_count + const resultCapturePostReleaseBlockedTransitions = resultCapturePostReleaseVerifierRollbackGate.rollups.blocked_post_release_transition_count + const resultCapturePostReleaseActions = resultCapturePostReleaseVerifierRollbackGate.rollups.operator_action_count + const resultCapturePostReleaseApprovalRequired = ( + resultCapturePostReleaseVerifierRollbackGate.rollups.approval_required_verifier_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.approval_required_rollback_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.approval_required_verification_hold_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.approval_required_live_apply_count + ) + const resultCapturePostReleaseBlocked = ( + resultCapturePostReleaseVerifierRollbackGate.rollups.blocked_verifier_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.blocked_rollback_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.blocked_verification_hold_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.blocked_live_apply_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.critical_blocker_count + ) + const resultCapturePostReleaseLiveWrites = ( + resultCapturePostReleaseVerifierRollbackGate.rollups.writer_apply_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.execution_apply_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.receipt_write_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.reviewer_queue_write_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.gateway_queue_write_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.telegram_send_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.bot_api_call_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.report_receipt_write_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.result_capture_write_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.learning_write_count + + resultCapturePostReleaseVerifierRollbackGate.rollups.playbook_trust_write_count + + resultCapturePostReleaseVerifierRollbackGate.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 @@ -7752,6 +7792,152 @@ export function AutomationInventoryTab() {
+
+
+
+ + + {t('resultCapturePostReleaseVerifierRollbackGate.title')} + +
+ +
+ +
+ } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> +
+ +
+
+ {t('resultCapturePostReleaseVerifierRollbackGate.priorTitle')} + + {resultCapturePostReleaseVerifierRollbackGate.prior_owner_release_approval_gate.readiness_note} + +
+ + + +
+
+ +
+ {t('resultCapturePostReleaseVerifierRollbackGate.truthTitle')} + + {resultCapturePostReleaseVerifierRollbackGate.post_release_verifier_truth.truth_note} + +
+ + + + + + +
+
+
+ +
+ {resultCapturePostReleaseVerifierRollbackGate.post_release_verifier_gates.slice(0, 5).map(gate => ( +
+
+ + {gate.display_name} + + +
+ + {gate.source_approval_gate} → {gate.verifier_summary} + +
+ + + + +
+
+ ))} +
+ +
+ {resultCapturePostReleaseVerifierRollbackGate.rollback_release_gates.slice(0, 5).map(gate => ( +
+
+ + {gate.display_name} + + +
+ + {gate.rollback_scope} + +
+ + + + +
+
+ ))} +
+ +
+ {resultCapturePostReleaseVerifierRollbackGate.live_apply_post_release_gates.slice(0, 5).map(gate => ( +
+
+ + {gate.display_name} + + +
+ + {gate.release_condition} + +
+ + + +
+
+ ))} +
+ +
+ {resultCapturePostReleaseVerifierRollbackGate.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 6f1e2b3f4..5bfb41ce6 100644 --- a/apps/web/src/lib/api-client.ts +++ b/apps/web/src/lib/api-client.ts @@ -555,6 +555,11 @@ export const apiClient = { return handleResponse(res) }, + async getAiAgentResultCapturePostReleaseVerifierRollbackGate() { + const res = await fetch(`${API_BASE_URL}/agents/agent-result-capture-post-release-verifier-rollback-gate`) + return handleResponse(res) + }, + async getAiAgentOwnerApprovedFixtureDryRun() { const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`) return handleResponse(res) @@ -7746,6 +7751,212 @@ export interface AiAgentResultCaptureOwnerReleaseApprovalGateSnapshot { } } +export interface AiAgentResultCapturePostReleaseVerifierRollbackGateSnapshot { + schema_version: 'ai_agent_result_capture_post_release_verifier_rollback_gate_v1' + generated_at: string + program_status: { + overall_completion_percent: number + current_priority: 'P0' | 'P1' | 'P2' | 'P3' + current_task_id: 'P2-132' + next_task_id: 'P2-133' + read_only_mode: true + runtime_authority: 'result_capture_post_release_verifier_rollback_gate_only_no_live_write' + status_note: string + } + source_refs: string[] + prior_owner_release_approval_gate: { + schema_version: string + owner_release_approval_packet_count: number + maintenance_window_approval_gate_count: number + live_apply_release_approval_gate_count: number + rollback_owner_approval_check_count: number + blocked_approval_transition_count: number + operator_action_count: number + approval_required_total: number + blocked_total: number + owner_release_approved_count: number + maintenance_window_approved_count: number + rollback_owner_confirmed_count: number + post_release_verifier_ready_count: number + release_approval_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 + readiness_note: string + } + post_release_verifier_truth: { + p2_131_approval_gate_loaded: boolean + post_release_verifier_gate_ready: boolean + rollback_release_gate_ready: boolean + release_verification_hold_active: boolean + live_apply_post_release_hold_active: boolean + owner_release_review_still_required: boolean + maintenance_window_review_still_required: boolean + rollback_owner_review_required: boolean + redaction_review_required: boolean + post_release_verifier_gate_only: boolean + owner_release_approved: boolean + maintenance_window_approved: boolean + rollback_owner_confirmed: boolean + post_release_verifier_ready: boolean + release_verification_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_approved_count: number + maintenance_window_approved_count: number + rollback_owner_confirmed_count: number + post_release_verifier_ready_count: number + release_verification_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 + } + post_release_verifier_gates: Array<{ + gate_id: string + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + source_approval_gate: string + status: 'ready_for_owner_review' | 'approval_required' | 'blocked_by_policy' + gate_mode: 'post_release_verifier_gate' + post_release_verifier_ready: false + release_verification_passed: false + verifier_summary: string + evidence_hash: string + }> + rollback_release_gates: Array<{ + gate_id: string + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + status: 'ready_for_owner_review' | 'approval_required' | 'blocked_by_policy' + gate_mode: 'rollback_release_gate' + rollback_owner_required: true + rollback_owner_confirmed: false + rollback_release_enabled: false + rollback_scope: string + }> + release_verification_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: 'release_verification_hold' + owner_release_approved: false + maintenance_window_approved: false + release_verification_passed: false + hold_reason: string + }> + live_apply_post_release_gates: Array<{ + gate_id: string + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + status: 'ready_for_owner_review' | 'approval_required' | 'blocked_by_policy' + gate_mode: 'live_apply_post_release_gate' + post_release_verifier_ready: false + live_apply_release_enabled: false + release_condition: string + }> + blocked_post_release_transitions: Array<{ + blocker_id: string + display_name: string + severity: 'high' | 'critical' + status: 'approval_required' | 'blocked_by_policy' + blocked_action: string + blocked_until: string + evidence_hash: string + }> + 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: { + post_release_verifier_gate_count: number + rollback_release_gate_count: number + release_verification_hold_count: number + live_apply_post_release_gate_count: number + blocked_post_release_transition_count: number + operator_action_count: number + approval_required_verifier_count: number + blocked_verifier_count: number + approval_required_rollback_count: number + blocked_rollback_count: number + approval_required_verification_hold_count: number + blocked_verification_hold_count: number + approval_required_live_apply_count: number + blocked_live_apply_count: number + critical_blocker_count: number + owner_release_approved_count: number + maintenance_window_approved_count: number + rollback_owner_confirmed_count: number + post_release_verifier_ready_count: number + release_verification_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 9379e2d4c..50421d1e6 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,28 @@ +## 2026-06-14|P2-132 Post-release verifier / rollback gate 本地完成,正式驗證待推進 + +**背景**:P2-131 已把 owner release approval gate 正式驗證完成;但 approval gate 仍不得被誤讀成 owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release verification passed 或 live apply release passed。P2-132 因此只建立 post-release verifier / rollback gate,把批准門檻轉成正式釋出後驗證與 rollback release 的可審核 hold,不開啟 verifier live read、不確認 rollback owner、不釋放 live apply、不套用 writer、不寫 receipt、不寫 result capture / learning / PlayBook trust / reviewer queue / Gateway queue,也不送 Telegram 或呼叫 Bot API。 + +**完成內容**: +- 新增 `ai_agent_result_capture_post_release_verifier_rollback_gate_v1` schema、committed snapshot、loader 與 API endpoint `GET /api/v1/agents/agent-result-capture-post-release-verifier-rollback-gate`。 +- P2-132 snapshot 固定 5 個 post-release verifier gate、5 個 rollback release gate、5 個 release verification hold、5 個 live-apply post-release gate、6 個 blocked post-release transition 與 5 個 operator action。 +- Governance automation inventory 頁新增 P2-132 區塊,顯示 P2-132 進度 `100%`、verifier gate `5`、rollback gate `5`、verification hold `5`、live-apply post gate `5`、blocked post-release `6`、operator action `5`、需批准 `8`、阻擋 `9`、正式寫入 / 發送 `0`。 +- Post-release verifier truth 固定為 `result_capture_post_release_verifier_rollback_gate_only_no_live_write`;owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release verification 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-132 schema / snapshot、`zh-TW.json`、`en.json` 通過。 +- Python 編譯:P2-132 loader 與 `agents.py` 通過。 +- API/service pytest:P2-132 + P2-131 regression `14 passed`。 +- Web typecheck:`pnpm --filter @awoooi/web typecheck` 通過。 +- Web production build:`NEXT_PUBLIC_API_URL=https://awoooi.wooo.work pnpm --filter @awoooi/web build` 通過;僅既有 Sentry setup / deprecation warning,governance First Load JS `434 kB`。 +- `git diff --check`、`doc-secrets-sanity-check.py docs .gitea`、`source-control-owner-response-guard.py --root .`、`security-mirror-progress-guard.py --root .` 通過。 + +**安全邊界**: +- P2-132 仍是 post-release verifier / rollback gate;不接受口頭批准、不把 approval gate 解讀成 owner release approved、不批准維護窗口、不確認 rollback owner、不啟用 post-release verifier live read、不釋放 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、不回傳內部協作內容。 + +**下一步**: +- 推送 P2-132 feature commit 到 Gitea main,等待 CD tests、build-and-deploy、post-deploy-checks 全綠,再做正式 API readback 與 desktop / mobile governance smoke。 +- `P2-133`:final release candidate readback;只有 P2-132 正式驗證後才可把 post-release verifier gate、rollback release gate、release verification hold、live-apply post-release gate 與 blocked post-release transition 轉成 release candidate readback,仍不得直接開啟 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-131 Owner release approval gate 完成與正式驗證 **背景**:P2-130 已把 owner-approved release readiness readback 正式驗證完成;但 readiness readback 仍不得被誤讀成 owner release approved、maintenance window approved 或 live apply passed。P2-131 因此只建立 owner release approval gate,把 readiness 轉成可審核批准門檻與 hold 證據,不接受口頭批准、不批准 owner release、不開維護窗口、不釋放 live apply、不套用 writer、不寫 receipt、不寫 result capture / learning / PlayBook trust / reviewer queue / Gateway queue,也不送 Telegram 或呼叫 Bot API。 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 bb4398024..5239a1586 100644 --- a/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md +++ b/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md @@ -12,17 +12,17 @@ | Nemotron 實際整合應用 | 30% | 完整回放前仍被關卡擋下 | `blocked_needs_evidence`,下一關是 `refresh_source_evidence_then_5_record_smoke_only` | | 工具 / 服務 / 套件 AI 自動化 | 92% | P0 已完成;P1 服務 / runtime / 監控 / provider / service health / 備份 / DR / 套件與供應鏈只讀基線已完成;P1-007 失敗限定通知合約與前端 redaction 合約已完成;下一主線是 P2-004 依賴 / 供應鏈漂移監控 | 狀態分類、盤點 schema、權限矩陣、靜態盤點種子、只讀 API、UI 骨架、驗證、自動化待辦 schema / 快照 / API / 分組 UI、Backup / DR 目標盤點、準備度矩陣、備份通知政策、Backup / DR 證據 UI、復原演練批准包模板、異地 / escrow 準備度狀態、任務批准邊界、確定性進度彙總、Python 套件 / 供應鏈只讀基線、JS pnpm/npm 只讀基線、Docker build surface 只讀基線、CVE / license / drift 嚴重度政策、定期依賴漂移與外部資料來源檢查設計、依賴升級批准包模板、runtime_surface_inventory_v1 schema / snapshot / API / UI、gitea_workflow_runner_health_v1 schema / snapshot / API / UI、observability_contract_matrix_v1 schema / snapshot / API / UI、ai_provider_route_matrix_v1 schema / snapshot / API / UI、service_health_gap_matrix_v1 schema / snapshot / API / UI、service health evidence cards UI、service_health_failure_notification_policy_v1 schema / snapshot / API / UI 已完成 | | OpenClaw / Hermes / NemoTron 佈建布局 | 45% | P1-401 / P1-402 已完成;仍是只讀 layout 與治理頁顯示,不是 runtime deploy | `ai_agent_deployment_layout_v1` schema、`ai_agent_deployment_layout_2026-06-11.json`、`GET /api/v1/agents/agent-deployment-layout`、治理頁自動化盤點 UI、`AI_AGENT_DEPLOYMENT_LAYOUT_2026-06-11.md` | -| OpenClaw / Hermes / NemoTron 主動溝通、學習與成長證據 | 100% | P2-401A 到 P2-131 已完成只讀證據面、runtime / report / result-capture 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;P2-131 已正式驗證,固定 5 個 owner release approval packet、5 個 maintenance window approval gate、5 個 live-apply release approval gate、5 個 rollback owner approval check、6 個 blocked approval transition 與 5 個 operator action。runtime worker、DB migration、production Redis consumer group、canonical runtime readback、live query、runtime score、result capture write、Telegram 實發、delivery receipt E2E、live report delivery、reviewer queue write、Gateway queue write、AI analysis runtime、中低風險 auto worker、KM / LOGBOOK / audit DB / timeline / PlayBook trust 寫入、SDK / 付費服務仍未開 gate | `ai_agent_result_capture_owner_release_approval_gate_v1`、`GET /api/v1/agents/agent-result-capture-owner-release-approval-gate`、正式站 deploy marker `03617db7`、正式站 `/zh-TW/governance?tab=automation-inventory` desktop / mobile smoke、`ai_agent_result_capture_owner_approved_release_readiness_readback_v1`、`GET /api/v1/agents/agent-result-capture-owner-approved-release-readiness-readback`、正式站 deploy marker `6fcf7241`、`ai_agent_result_capture_owner_approved_preflight_release_package_v1`、`GET /api/v1/agents/agent-result-capture-owner-approved-preflight-release-package`、`ai_agent_result_capture_owner_acceptance_readback_preflight_hold_v1`、`GET /api/v1/agents/agent-result-capture-owner-acceptance-readback-preflight-hold`、`ai_agent_result_capture_owner_acceptance_maintenance_gate_v1`、`GET /api/v1/agents/agent-result-capture-owner-acceptance-maintenance-gate`、`ai_agent_result_capture_owner_approved_execution_rehearsal_v1`、`GET /api/v1/agents/agent-result-capture-owner-approved-execution-rehearsal`、`ai_agent_result_capture_owner_promotion_review_v1`、`ai_agent_result_capture_writer_dry_run_readback_v1`、`ai_agent_result_capture_writer_dry_run_fixture_v1`、`ai_agent_result_capture_writer_implementation_review_v1`、`ai_agent_result_capture_write_gate_review_v1`、`ai_agent_interaction_learning_proof_v1`、MASTER §3.2.1b / §3.2.1d / §3.4.3 | +| OpenClaw / Hermes / NemoTron 主動溝通、學習與成長證據 | 100% | P2-401A 到 P2-132 已完成只讀證據面、runtime / report / result-capture 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;P2-132 已本地驗證,固定 5 個 post-release verifier gate、5 個 rollback release gate、5 個 release verification hold、5 個 live-apply post-release gate、6 個 blocked post-release transition 與 5 個 operator action,正式站 CD / API / smoke 待推進。runtime worker、DB migration、production Redis consumer group、canonical runtime readback、live query、runtime score、result capture write、Telegram 實發、delivery receipt E2E、live report delivery、reviewer queue write、Gateway queue write、AI analysis runtime、中低風險 auto worker、KM / LOGBOOK / audit DB / timeline / PlayBook trust 寫入、SDK / 付費服務仍未開 gate | `ai_agent_result_capture_post_release_verifier_rollback_gate_v1`、`GET /api/v1/agents/agent-result-capture-post-release-verifier-rollback-gate`、`ai_agent_result_capture_owner_release_approval_gate_v1`、`GET /api/v1/agents/agent-result-capture-owner-release-approval-gate`、正式站 deploy marker `03617db7`、正式站 `/zh-TW/governance?tab=automation-inventory` desktop / mobile smoke、`ai_agent_result_capture_owner_approved_release_readiness_readback_v1`、`GET /api/v1/agents/agent-result-capture-owner-approved-release-readiness-readback`、正式站 deploy marker `6fcf7241`、`ai_agent_result_capture_owner_approved_preflight_release_package_v1`、`GET /api/v1/agents/agent-result-capture-owner-approved-preflight-release-package`、`ai_agent_result_capture_owner_acceptance_readback_preflight_hold_v1`、`GET /api/v1/agents/agent-result-capture-owner-acceptance-readback-preflight-hold`、`ai_agent_result_capture_owner_acceptance_maintenance_gate_v1`、`GET /api/v1/agents/agent-result-capture-owner-acceptance-maintenance-gate`、`ai_agent_result_capture_owner_approved_execution_rehearsal_v1`、`GET /api/v1/agents/agent-result-capture-owner-approved-execution-rehearsal`、`ai_agent_result_capture_owner_promotion_review_v1`、`ai_agent_result_capture_writer_dry_run_readback_v1`、`ai_agent_result_capture_writer_dry_run_fixture_v1`、`ai_agent_result_capture_writer_implementation_review_v1`、`ai_agent_result_capture_write_gate_review_v1`、`ai_agent_interaction_learning_proof_v1`、MASTER §3.2.1b / §3.2.1d / §3.4.3 | | AI Agent 主動營運委派與版本生命週期 | 100% | P2-402A / P2-402B / P2-402C / P2-402D / P2-402E / P2-402F / P2-402G 已完成;已建立 repo-only 版本新鮮度快照、工具採用批准包、Telegram action-required digest policy、Gitea PR 草案 lane、host / K3s / stateful 版本只讀盤點、API 與 governance UI。定期排程、外部版本查詢、工具安裝、CI 變更、套件升級、主機更新、container pull、實際 PR creation、auto merge、Telegram 實發、SSH、kubectl、重啟仍未開 gate | `ai_agent_proactive_operations_contract_v1`、`ai_agent_version_freshness_snapshot_v1`、`ai_agent_tool_adoption_approval_package_v1`、`ai_agent_telegram_action_required_digest_policy_v1`、`ai_agent_gitea_pr_draft_lane_v1`、`ai_agent_host_stateful_version_inventory_v1`、`GET /api/v1/agents/agent-proactive-operations-contract`、`GET /api/v1/agents/agent-version-freshness-snapshot`、`GET /api/v1/agents/agent-tool-adoption-approval-package`、`GET /api/v1/agents/agent-telegram-action-required-digest-policy`、`GET /api/v1/agents/agent-gitea-pr-draft-lane`、`GET /api/v1/agents/agent-host-stateful-version-inventory`、`/zh-TW/governance?tab=automation-inventory`、MASTER §3.2.1c | | 本工作清單與分析報告 | 100% | 已完成 | 本 MD 文件 | -AI Agent 自動化工作包目前完成度:**99.3%**。本工作清單文件本身完成度:**100%**。 +AI Agent 自動化工作包目前完成度:**99.4%**。本工作清單文件本身完成度:**100%**。 三 Agent 佈建布局目前完成度:**45%**。第一波已完成只讀 schema / snapshot / API / 測試 / 報告,第二波已接入治理頁自動化盤點 UI;正式 runtime 佈署、Telegram E2E 發送與 AgentSession 工作流仍需逐項 gate。 -三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。P2-403A 到 P2-131 已把互動證據、報表治理、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 全部固定成可驗證證據。P2-131 已正式驗證,deploy marker `03617db7`,固定 5 個 owner release approval packet、5 個 maintenance window approval gate、5 個 live-apply release approval gate、5 個 rollback owner approval check、6 個 blocked approval transition 與 5 個 operator action;正式 API、desktop / mobile smoke、禁用內部協作片語 `0`、水平溢位 `0`、P2-131 危險入口 `0` 均通過。目前 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-132`。 +三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。P2-403A 到 P2-132 已把互動證據、報表治理、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 全部固定成可驗證證據。P2-132 已本地驗證,固定 5 個 post-release verifier gate、5 個 rollback release gate、5 個 release verification hold、5 個 live-apply post-release gate、6 個 blocked post-release transition 與 5 個 operator action;正式 API、desktop / mobile smoke 待 CD 完成後驗證。目前 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-133`。 -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-131` 已補互動、學習證據面、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。下一步是 `P2-132`;外部 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-132` 已補互動、學習證據面、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。下一步是 `P2-133`;外部 registry / package source / host probe / SSH / kubectl / 工具安裝 / CI 變更 / 實際 PR creation / Telegram 實發與 learning write 仍需 gate。 完成度計算模型: diff --git a/docs/evaluations/ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json b/docs/evaluations/ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json new file mode 100644 index 000000000..1c5a41d0b --- /dev/null +++ b/docs/evaluations/ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json @@ -0,0 +1,470 @@ +{ + "schema_version": "ai_agent_result_capture_post_release_verifier_rollback_gate_v1", + "generated_at": "2026-06-14T05:18:00+08:00", + "program_status": { + "overall_completion_percent": 100, + "current_priority": "P2", + "current_task_id": "P2-132", + "next_task_id": "P2-133", + "read_only_mode": true, + "runtime_authority": "result_capture_post_release_verifier_rollback_gate_only_no_live_write", + "status_note": "P2-132 只把 P2-131 owner release approval gate 轉成 post-release verifier / rollback gate;不得視為 owner release approved,不得批准 maintenance window,不得確認 rollback owner,不得釋放 live apply、套用 writer、寫 receipt、寫 result capture、寫 learning、寫 queue、送 Telegram 或寫入 production。" + }, + "source_refs": [ + "docs/evaluations/ai_agent_result_capture_owner_release_approval_gate_2026-06-14.json", + "docs/evaluations/ai_agent_result_capture_owner_approved_release_readiness_readback_2026-06-14.json", + "docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md#52-建立-owner-release-approval-gate" + ], + "prior_owner_release_approval_gate": { + "schema_version": "ai_agent_result_capture_owner_release_approval_gate_v1", + "owner_release_approval_packet_count": 5, + "maintenance_window_approval_gate_count": 5, + "live_apply_release_approval_gate_count": 5, + "rollback_owner_approval_check_count": 5, + "blocked_approval_transition_count": 6, + "operator_action_count": 5, + "approval_required_total": 8, + "blocked_total": 9, + "owner_release_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "release_approval_pass_count": 0, + "live_apply_release_pass_count": 0, + "writer_apply_count": 0, + "execution_apply_count": 0, + "receipt_write_count": 0, + "result_capture_write_count": 0, + "learning_write_count": 0, + "playbook_trust_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, + "readiness_note": "P2-131 已把 owner release approval packet、maintenance window approval gate、live-apply approval gate、rollback owner approval check 與 blocked approval transition 固定為只讀 approval gate;P2-132 只建立 post-release verifier / rollback gate,不視為正式批准。" + }, + "post_release_verifier_truth": { + "p2_131_approval_gate_loaded": true, + "post_release_verifier_gate_ready": true, + "rollback_release_gate_ready": true, + "release_verification_hold_active": true, + "live_apply_post_release_hold_active": true, + "owner_release_review_still_required": true, + "maintenance_window_review_still_required": true, + "rollback_owner_review_required": true, + "redaction_review_required": true, + "post_release_verifier_gate_only": true, + "owner_release_approved": false, + "maintenance_window_approved": false, + "rollback_owner_confirmed": false, + "post_release_verifier_ready": false, + "release_verification_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_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "release_verification_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-132 只建立 post-release verifier / rollback gate;verifier gate 可見不代表 post-release verifier ready、rollback owner confirmed、release verification passed 或 live apply 可執行。" + }, + "post_release_verifier_gates": [ + { + "gate_id": "post_release_verifier_result_capture", + "display_name": "Result capture post-release verifier gate", + "owner_agent": "openclaw", + "source_approval_gate": "approval_gate_result_capture_writer", + "status": "ready_for_owner_review", + "gate_mode": "post_release_verifier_gate", + "post_release_verifier_ready": false, + "release_verification_passed": false, + "verifier_summary": "建立 result capture post-release verifier gate;未取得 owner approval、maintenance window 與 rollback owner 前不得寫 receipt 或 result capture。", + "evidence_hash": "sha256:d111111111111111111111111111111111111111111111111111111111111111" + }, + { + "gate_id": "post_release_verifier_learning", + "display_name": "Learning post-release verifier gate", + "owner_agent": "hermes", + "source_approval_gate": "approval_gate_learning_writer", + "status": "approval_required", + "gate_mode": "post_release_verifier_gate", + "post_release_verifier_ready": false, + "release_verification_passed": false, + "verifier_summary": "建立 learning verifier gate;不寫 KM、不寫 learning metadata、不更新 PlayBook trust。", + "evidence_hash": "sha256:d222222222222222222222222222222222222222222222222222222222222222" + }, + { + "gate_id": "post_release_verifier_playbook_trust", + "display_name": "PlayBook trust post-release verifier gate", + "owner_agent": "nemotron", + "source_approval_gate": "approval_gate_playbook_trust_writer", + "status": "blocked_by_policy", + "gate_mode": "post_release_verifier_gate", + "post_release_verifier_ready": false, + "release_verification_passed": false, + "verifier_summary": "PlayBook trust 仍需 OpenClaw 仲裁與負向強化 reviewer;未完成前不得 release verification pass。", + "evidence_hash": "sha256:d333333333333333333333333333333333333333333333333333333333333333" + }, + { + "gate_id": "post_release_verifier_reviewer_queue", + "display_name": "Reviewer queue post-release verifier gate", + "owner_agent": "openclaw", + "source_approval_gate": "approval_gate_reviewer_queue_writer", + "status": "approval_required", + "gate_mode": "post_release_verifier_gate", + "post_release_verifier_ready": false, + "release_verification_passed": false, + "verifier_summary": "建立 reviewer queue verifier gate;不寫 reviewer queue、不建立 live queue item。", + "evidence_hash": "sha256:d444444444444444444444444444444444444444444444444444444444444444" + }, + { + "gate_id": "post_release_verifier_gateway_queue", + "display_name": "Gateway queue post-release verifier gate", + "owner_agent": "nemotron", + "source_approval_gate": "approval_gate_gateway_queue_writer", + "status": "ready_for_owner_review", + "gate_mode": "post_release_verifier_gate", + "post_release_verifier_ready": false, + "release_verification_passed": false, + "verifier_summary": "建立 Gateway queue verifier gate;不寫 Gateway queue、不送 Telegram、不呼叫 Bot API。", + "evidence_hash": "sha256:d555555555555555555555555555555555555555555555555555555555555555" + } + ], + "rollback_release_gates": [ + { + "gate_id": "rollback_release_result_capture", + "display_name": "Result capture rollback release gate", + "owner_agent": "openclaw", + "status": "ready_for_owner_review", + "gate_mode": "rollback_release_gate", + "rollback_owner_required": true, + "rollback_owner_confirmed": false, + "rollback_release_enabled": false, + "rollback_scope": "撤回 result capture verifier gate、receipt preview 與 release candidate handoff。" + }, + { + "gate_id": "rollback_release_learning", + "display_name": "Learning rollback release gate", + "owner_agent": "hermes", + "status": "approval_required", + "gate_mode": "rollback_release_gate", + "rollback_owner_required": true, + "rollback_owner_confirmed": false, + "rollback_release_enabled": false, + "rollback_scope": "撤回 learning verifier gate、KM write scope 與 stale guard handoff。" + }, + { + "gate_id": "rollback_release_playbook_trust", + "display_name": "PlayBook trust rollback release gate", + "owner_agent": "nemotron", + "status": "blocked_by_policy", + "gate_mode": "rollback_release_gate", + "rollback_owner_required": true, + "rollback_owner_confirmed": false, + "rollback_release_enabled": false, + "rollback_scope": "撤回 PlayBook trust verifier gate、trust delta 與 reviewer handoff。" + }, + { + "gate_id": "rollback_release_reviewer_queue", + "display_name": "Reviewer queue rollback release gate", + "owner_agent": "openclaw", + "status": "approval_required", + "gate_mode": "rollback_release_gate", + "rollback_owner_required": true, + "rollback_owner_confirmed": false, + "rollback_release_enabled": false, + "rollback_scope": "撤回 reviewer queue verifier gate、dedupe key 與 SLA handoff。" + }, + { + "gate_id": "rollback_release_gateway_queue", + "display_name": "Gateway queue rollback release gate", + "owner_agent": "nemotron", + "status": "ready_for_owner_review", + "gate_mode": "rollback_release_gate", + "rollback_owner_required": true, + "rollback_owner_confirmed": false, + "rollback_release_enabled": false, + "rollback_scope": "撤回 Gateway queue verifier gate、route lock 與 Telegram receipt draft。" + } + ], + "release_verification_holds": [ + { + "hold_id": "verification_hold_result_capture", + "display_name": "Result capture verification hold", + "owner_agent": "openclaw", + "status": "ready_for_owner_review", + "hold_mode": "release_verification_hold", + "owner_release_approved": false, + "maintenance_window_approved": false, + "release_verification_passed": false, + "hold_reason": "owner release approved、maintenance window approved、rollback owner confirmed 與 post-release verifier ready 尚未成立。" + }, + { + "hold_id": "verification_hold_learning", + "display_name": "Learning verification hold", + "owner_agent": "hermes", + "status": "approval_required", + "hold_mode": "release_verification_hold", + "owner_release_approved": false, + "maintenance_window_approved": false, + "release_verification_passed": false, + "hold_reason": "learning write scope、KM owner、rollback owner 與 maintenance window 尚未 approved。" + }, + { + "hold_id": "verification_hold_playbook_trust", + "display_name": "PlayBook trust verification hold", + "owner_agent": "nemotron", + "status": "blocked_by_policy", + "hold_mode": "release_verification_hold", + "owner_release_approved": false, + "maintenance_window_approved": false, + "release_verification_passed": false, + "hold_reason": "OpenClaw 仲裁、trust reviewer 與負向強化審查尚未完成。" + }, + { + "hold_id": "verification_hold_reviewer_queue", + "display_name": "Reviewer queue verification hold", + "owner_agent": "openclaw", + "status": "approval_required", + "hold_mode": "release_verification_hold", + "owner_release_approved": false, + "maintenance_window_approved": false, + "release_verification_passed": false, + "hold_reason": "reviewer queue owner、rollback owner 與 maintenance window 尚未 approved。" + }, + { + "hold_id": "verification_hold_gateway_queue", + "display_name": "Gateway queue verification hold", + "owner_agent": "nemotron", + "status": "ready_for_owner_review", + "hold_mode": "release_verification_hold", + "owner_release_approved": false, + "maintenance_window_approved": false, + "release_verification_passed": false, + "hold_reason": "Telegram receipt owner、SRE route lock 與 maintenance window 尚未 approved。" + } + ], + "live_apply_post_release_gates": [ + { + "gate_id": "live_apply_post_release_result_capture", + "display_name": "Result capture live apply post-release gate", + "owner_agent": "openclaw", + "status": "ready_for_owner_review", + "gate_mode": "live_apply_post_release_gate", + "post_release_verifier_ready": false, + "live_apply_release_enabled": false, + "release_condition": "P2-133 只能先建立 final release candidate readback,不得直接 writer apply。" + }, + { + "gate_id": "live_apply_post_release_learning", + "display_name": "Learning live apply post-release gate", + "owner_agent": "hermes", + "status": "approval_required", + "gate_mode": "live_apply_post_release_gate", + "post_release_verifier_ready": false, + "live_apply_release_enabled": false, + "release_condition": "需要 owner release approval gate、maintenance window gate、rollback gate 與 verifier gate 同時通過。" + }, + { + "gate_id": "live_apply_post_release_playbook_trust", + "display_name": "PlayBook trust live apply post-release gate", + "owner_agent": "nemotron", + "status": "blocked_by_policy", + "gate_mode": "live_apply_post_release_gate", + "post_release_verifier_ready": false, + "live_apply_release_enabled": false, + "release_condition": "不得因 verifier gate 可見而自動更新 PlayBook trust。" + }, + { + "gate_id": "live_apply_post_release_reviewer_queue", + "display_name": "Reviewer queue live apply post-release gate", + "owner_agent": "openclaw", + "status": "approval_required", + "gate_mode": "live_apply_post_release_gate", + "post_release_verifier_ready": false, + "live_apply_release_enabled": false, + "release_condition": "不得寫 reviewer queue,僅保留 final candidate readback。" + }, + { + "gate_id": "live_apply_post_release_gateway_queue", + "display_name": "Gateway queue live apply post-release gate", + "owner_agent": "nemotron", + "status": "ready_for_owner_review", + "gate_mode": "live_apply_post_release_gate", + "post_release_verifier_ready": false, + "live_apply_release_enabled": false, + "release_condition": "不得寫 Gateway queue、不得送 Telegram、不得呼叫 Bot API。" + } + ], + "blocked_post_release_transitions": [ + { + "blocker_id": "blocked_writer_apply_post_release", + "display_name": "Writer apply post-release blocked", + "severity": "critical", + "status": "blocked_by_policy", + "blocked_action": "writer_apply_after_post_release_verifier_gate", + "blocked_until": "owner release approved + maintenance window approved + post-release verifier ready + rollback owner confirmed", + "evidence_hash": "sha256:e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1" + }, + { + "blocker_id": "blocked_execution_apply_post_release", + "display_name": "Execution apply post-release blocked", + "severity": "critical", + "status": "blocked_by_policy", + "blocked_action": "execution_apply_after_post_release_verifier_gate", + "blocked_until": "maintenance window approved + rollback release gate passed", + "evidence_hash": "sha256:e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2" + }, + { + "blocker_id": "blocked_receipt_write_post_release", + "display_name": "Receipt write post-release blocked", + "severity": "critical", + "status": "approval_required", + "blocked_action": "receipt_write_after_post_release_verifier_gate", + "blocked_until": "post-release verifier ready + release verification passed", + "evidence_hash": "sha256:e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3" + }, + { + "blocker_id": "blocked_result_capture_write_post_release", + "display_name": "Result capture write post-release blocked", + "severity": "critical", + "status": "blocked_by_policy", + "blocked_action": "result_capture_write_after_post_release_verifier_gate", + "blocked_until": "owner release approved + result capture verifier ready + rollback owner confirmed", + "evidence_hash": "sha256:e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4e4" + }, + { + "blocker_id": "blocked_gateway_queue_write_post_release", + "display_name": "Gateway queue write post-release blocked", + "severity": "critical", + "status": "approval_required", + "blocked_action": "gateway_queue_write_after_post_release_verifier_gate", + "blocked_until": "SRE route lock + Telegram receipt owner approved + post-release verifier ready", + "evidence_hash": "sha256:e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5" + }, + { + "blocker_id": "blocked_telegram_send_post_release", + "display_name": "Telegram send post-release blocked", + "severity": "high", + "status": "approval_required", + "blocked_action": "telegram_send_after_post_release_verifier_gate", + "blocked_until": "Gateway queue release approved + Telegram receipt E2E approved + rollback release gate passed", + "evidence_hash": "sha256:e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6e6" + } + ], + "operator_actions": [ + { + "action_id": "review_post_release_verifier_gates", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "審核 5 個 post-release verifier gate 是否仍符合 P2-131 approval gate 邊界;不要把 verifier gate 視為正式批准。", + "runtime_write_allowed": false + }, + { + "action_id": "verify_rollback_release_gate", + "owner_agent": "hermes", + "status": "ready_for_operator_review", + "operator_instruction": "確認 rollback release gate 仍全部未 confirmed,且 rollback_release_enabled 仍為 false。", + "runtime_write_allowed": false + }, + { + "action_id": "verify_release_verification_hold", + "owner_agent": "nemotron", + "status": "ready_for_operator_review", + "operator_instruction": "確認 release verification hold 已讀回但仍 hold;不可套用 writer 或執行正式寫入。", + "runtime_write_allowed": false + }, + { + "action_id": "verify_live_apply_post_release_hold", + "owner_agent": "openclaw", + "status": "approval_required", + "operator_instruction": "確認 live apply post-release gate 仍未 enabled,且 post_release_verifier_ready 仍為 false。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_p2_133_final_release_candidate_readback", + "owner_agent": "hermes", + "status": "ready_for_operator_review", + "operator_instruction": "下一關只可建立 P2-133 final release candidate readback,不可放行 writer 或正式寫入。", + "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": "前端只能顯示 post-release verifier / rollback gate 摘要、狀態、數量、紅acted hash 與 0 / false 邊界;不得顯示內部協作環境對話、原始提示詞、私有推理、secret、授權標頭或原始 runtime payload。" + }, + "rollups": { + "post_release_verifier_gate_count": 5, + "rollback_release_gate_count": 5, + "release_verification_hold_count": 5, + "live_apply_post_release_gate_count": 5, + "blocked_post_release_transition_count": 6, + "operator_action_count": 5, + "approval_required_verifier_count": 2, + "blocked_verifier_count": 1, + "approval_required_rollback_count": 2, + "blocked_rollback_count": 1, + "approval_required_verification_hold_count": 2, + "blocked_verification_hold_count": 1, + "approval_required_live_apply_count": 2, + "blocked_live_apply_count": 1, + "critical_blocker_count": 5, + "owner_release_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "release_verification_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_post_release_verifier_rollback_gate_v1.schema.json b/docs/schemas/ai_agent_result_capture_post_release_verifier_rollback_gate_v1.schema.json new file mode 100644 index 000000000..6105ef5f7 --- /dev/null +++ b/docs/schemas/ai_agent_result_capture_post_release_verifier_rollback_gate_v1.schema.json @@ -0,0 +1,100 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://awoooi.wooo.work/schemas/ai_agent_result_capture_post_release_verifier_rollback_gate_v1.schema.json", + "title": "AI Agent result capture post-release verifier rollback gate v1", + "type": "object", + "required": [ + "schema_version", + "generated_at", + "program_status", + "source_refs", + "prior_owner_release_approval_gate", + "post_release_verifier_truth", + "post_release_verifier_gates", + "rollback_release_gates", + "release_verification_holds", + "live_apply_post_release_gates", + "blocked_post_release_transitions", + "operator_actions", + "display_redaction_contract", + "rollups" + ], + "properties": { + "schema_version": { + "const": "ai_agent_result_capture_post_release_verifier_rollback_gate_v1" + }, + "generated_at": { + "type": "string" + }, + "program_status": { + "type": "object" + }, + "source_refs": { + "type": "array", + "items": { + "type": "string" + } + }, + "prior_owner_release_approval_gate": { + "type": "object" + }, + "post_release_verifier_truth": { + "type": "object" + }, + "post_release_verifier_gates": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object" + } + }, + "rollback_release_gates": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object" + } + }, + "release_verification_holds": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object" + } + }, + "live_apply_post_release_gates": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object" + } + }, + "blocked_post_release_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 348139e55..21e1df463 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 @@ -668,7 +668,8 @@ Alert / Sentry / SigNoz / Gitea / Market Watch / Operator | `docs/evaluations/ai_agent_result_capture_owner_acceptance_readback_preflight_hold_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-owner-acceptance-readback-preflight-hold` | P2-128 owner acceptance readback / live-apply preflight hold;承接 P2-127 owner acceptance / maintenance window gate,建立 5 個 owner acceptance readback、5 個 preflight hold check、5 個 live-apply hold gate、5 個 rollback preflight check、6 個 blocked apply transition 與 5 個 operator action;runtime authority 固定 `result_capture_owner_acceptance_readback_preflight_hold_only_no_live_write`;owner acceptance received、maintenance window approved、rollback owner confirmed、post-apply verifier ready、live apply preflight 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 `0a3f1533` 已正式驗證,已由 P2-129 承接 | | `docs/evaluations/ai_agent_result_capture_owner_approved_preflight_release_package_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-owner-approved-preflight-release-package` | P2-129 owner-approved preflight release package;承接 P2-128 owner acceptance readback / live-apply preflight hold,建立 5 個 owner-approved release package、5 個 release preflight check、5 個 live-apply release gate、5 個 rollback release check、6 個 blocked release transition 與 5 個 operator action;runtime authority 固定 `result_capture_owner_approved_preflight_release_package_only_no_live_write`;owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、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 `7e5b4793` 已正式驗證,已由 P2-130 承接 | | `docs/evaluations/ai_agent_result_capture_owner_approved_release_readiness_readback_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-owner-approved-release-readiness-readback` | P2-130 owner-approved release readiness readback;承接 P2-129 owner-approved preflight release package,建立 5 個 release readiness readback、5 個 owner release readiness check、5 個 live-apply readiness gate、5 個 rollback readiness check、6 個 blocked readiness transition 與 5 個 operator action;runtime authority 固定 `result_capture_owner_approved_release_readiness_readback_only_no_live_write`;owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release readiness 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 `6fcf7241` 已正式驗證,下一步 P2-131 | -| `docs/evaluations/ai_agent_result_capture_owner_release_approval_gate_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-owner-release-approval-gate` | P2-131 owner release approval gate;承接 P2-130 owner-approved release readiness readback,建立 5 個 owner release approval packet、5 個 maintenance window approval gate、5 個 live-apply release approval gate、5 個 rollback owner approval check、6 個 blocked approval transition 與 5 個 operator action;runtime authority 固定 `result_capture_owner_release_approval_gate_only_no_live_write`;owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release approval 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 `03617db7` 已正式驗證,下一步 P2-132 | +| `docs/evaluations/ai_agent_result_capture_owner_release_approval_gate_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-owner-release-approval-gate` | P2-131 owner release approval gate;承接 P2-130 owner-approved release readiness readback,建立 5 個 owner release approval packet、5 個 maintenance window approval gate、5 個 live-apply release approval gate、5 個 rollback owner approval check、6 個 blocked approval transition 與 5 個 operator action;runtime authority 固定 `result_capture_owner_release_approval_gate_only_no_live_write`;owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release approval 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 `03617db7` 已正式驗證,已由 P2-132 承接 | +| `docs/evaluations/ai_agent_result_capture_post_release_verifier_rollback_gate_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-post-release-verifier-rollback-gate` | P2-132 post-release verifier / rollback gate;承接 P2-131 owner release approval gate,建立 5 個 post-release verifier gate、5 個 rollback release gate、5 個 release verification hold、5 個 live-apply post-release gate、6 個 blocked post-release transition 與 5 個 operator action;runtime authority 固定 `result_capture_post_release_verifier_rollback_gate_only_no_live_write`;owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release verification 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`;本地測試 / build / guard 已通過,正式 CD 與 production smoke 待推進,下一步 P2-133 | | `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 主動營運委派與版本生命週期契約 @@ -789,6 +790,7 @@ Repo / registry / release notes / K8s / host / observability / backup evidence 50. 建立 owner-approved preflight release package。✅ P2-129 已完成並正式驗證;owner-approved release package `5`、release preflight check `5`、live-apply release gate `5`、rollback release check `5`、blocked release transition `6`、operator action `5`,approval-required package / preflight / release gate / rollback `2 / 2 / 2 / 2`、blocked package / preflight / release gate / rollback `1 / 1 / 1 / 1`、critical blocker `5`;owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、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 `7e5b4793`、正式 API readback 與 desktop / mobile smoke 已完成。已由 P2-130 承接。 51. 建立 owner-approved release readiness readback。✅ P2-130 已完成並正式驗證;release readiness readback `5`、owner release readiness check `5`、live-apply readiness gate `5`、rollback readiness check `5`、blocked readiness transition `6`、operator action `5`,approval-required readback / owner check / readiness gate / rollback `2 / 2 / 2 / 2`、blocked readback / owner check / readiness gate / rollback `1 / 1 / 1 / 1`、critical blocker `5`;owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release readiness 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 `6fcf7241`、正式 API readback 與 desktop / mobile smoke 已完成。已由 P2-131 承接。 52. 建立 owner release approval gate。✅ P2-131 已完成並正式驗證;owner release approval packet `5`、maintenance window approval gate `5`、live-apply release approval gate `5`、rollback owner approval check `5`、blocked approval transition `6`、operator action `5`,approval-required packet / maintenance / live apply / rollback `2 / 2 / 2 / 2`、blocked packet / maintenance / live apply / rollback `1 / 1 / 1 / 1`、critical blocker `5`;owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release approval 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 `03617db7`、正式 API readback 與 desktop / mobile smoke 已完成。已由 P2-132 承接。 +53. 建立 post-release verifier / rollback gate。🟡 P2-132 已本地完成,正式驗證待推進;post-release verifier gate `5`、rollback release gate `5`、release verification hold `5`、live-apply post-release gate `5`、blocked post-release transition `6`、operator action `5`,approval-required verifier / rollback / verification / live apply `2 / 2 / 2 / 2`、blocked verifier / rollback / verification / live apply `1 / 1 / 1 / 1`、critical blocker `5`;owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release verification 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`;本地 API/service regression、typecheck、production build 與 guard 已完成。正式 API readback 與 desktop / mobile smoke 完成後才可由 P2-133 承接。 #### 3.2.1d 2026-06-11 Agent 互動、學習與成長證據面 @@ -2109,6 +2111,16 @@ Phase 6 完成後 - 政策裁決:P2-126 只允許 owner-approved execution rehearsal、no-write apply check、post-write verifier rehearsal、rollback drill、blocked live apply 與 operator handoff 可視化;不得把 rehearsal 解讀成 owner approval record 已收、no-write apply 已執行、writer apply、execution apply、receipt write、result capture write、learning write、PlayBook trust write、reviewer queue write、Gateway queue write、Telegram 實發、Bot API 呼叫、report receipt write 或 live writer 已啟用。 - 本波仍不讀 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-127 承接。 +### 2026-06-14 07:46 (台北) — §3.2 / §5 — 本地完成 P2-132 post-release verifier / rollback gate — 把 release approval 轉成釋出後驗證與 rollback hold + +- 新增 `ai_agent_result_capture_post_release_verifier_rollback_gate_v1` schema / committed snapshot / loader / API / 測試,承接 P2-131 owner release approval gate,定義 5 個 post-release verifier gate、5 個 rollback release gate、5 個 release verification hold、5 個 live-apply post-release gate、6 個 blocked post-release transition 與 5 個 operator action。 +- Governance automation inventory 新增 P2-132 區塊,將 post-release verifier gate、rollback release gate、release verification hold、live-apply post-release gate、blocked post-release transition 與 operator action 全部以只讀方式呈現。 +- 本地 API/service regression:P2-132 + P2-131 `14 passed`;JSON parse、Python 3.11 py_compile、`pnpm --filter @awoooi/web typecheck` 與 production build 通過;`git diff --check`、`doc-secrets-sanity-check.py docs .gitea`、`source-control-owner-response-guard.py --root .`、`security-mirror-progress-guard.py --root .` 通過。 +- 本地 snapshot 固定 `schema_version=ai_agent_result_capture_post_release_verifier_rollback_gate_v1`、current `P2-132`、next `P2-133`、completion `100`;post-release verifier gate `5`、rollback release gate `5`、release verification hold `5`、live-apply post-release gate `5`、blocked post-release transition `6`、operator action `5`、approval-required verifier / rollback / verification / live apply `2 / 2 / 2 / 2`、blocked verifier / rollback / verification / live apply `1 / 1 / 1 / 1`、critical blocker `5`。 +- 本地 0 / false 邊界:owner release approved、maintenance window approved、rollback owner confirmed、post-release verifier ready、release verification 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`。 +- 政策裁決:P2-132 只允許 post-release verifier / rollback gate 可視化;不得把 verifier gate 解讀成 post-release verifier ready、release verification 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 實發、Bot API 呼叫、report receipt write 或 live writer 已啟用。 +- 本波仍不讀 canonical runtime target、不做 live query、不寫 reviewer queue、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不寫 result capture、不寫 learning、不更新 PlayBook trust、不寫 production target、不讀 secret、不執行 destructive action、不回傳內部協作內容;正式 CD / production API / desktop mobile smoke 通過後才可由 P2-133 承接。 + ### 2026-06-14 07:08 (台北) — §3.2 / §5 — 完成並正式驗證 P2-131 owner release approval gate — 把 readiness 轉成可審核批准門檻 - 新增 `ai_agent_result_capture_owner_release_approval_gate_v1` schema / committed snapshot / loader / API / 測試,承接 P2-130 owner-approved release readiness readback,定義 5 個 owner release approval packet、5 個 maintenance window approval gate、5 個 live-apply release approval gate、5 個 rollback owner approval check、6 個 blocked approval transition 與 5 個 operator action。