From 755b0a8d3038df2c52dee280067863d92db1eda5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 14 Jun 2026 14:37:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(governance):=20=E6=96=B0=E5=A2=9E=20P2-143?= =?UTF-8?q?=20owner=20response=20=E9=A0=90=E6=AA=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api/src/api/v1/agents.py | 33 ++ ...lease_decision_owner_response_preflight.py | 376 +++++++++++++++++ ...lease_decision_owner_response_preflight.py | 110 +++++ ...e_decision_owner_response_preflight_api.py | 49 +++ apps/web/messages/en.json | 37 ++ apps/web/messages/zh-TW.json | 37 ++ .../tabs/automation-inventory-tab.tsx | 157 ++++++- apps/web/src/lib/api-client.ts | 125 +++++- docs/LOGBOOK.md | 32 ++ ...AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md | 19 +- ...n_owner_response_preflight_2026-06-14.json | 394 ++++++++++++++++++ ...-04-15-MASTER-ai-autonomous-flywheel-v2.md | 4 + 12 files changed, 1366 insertions(+), 7 deletions(-) create mode 100644 apps/api/src/services/ai_agent_result_capture_release_decision_owner_response_preflight.py create mode 100644 apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_preflight.py create mode 100644 apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_preflight_api.py create mode 100644 docs/evaluations/ai_agent_result_capture_release_decision_owner_response_preflight_2026-06-14.json diff --git a/apps/api/src/api/v1/agents.py b/apps/api/src/api/v1/agents.py index 4bab293d..6ede35b3 100644 --- a/apps/api/src/api/v1/agents.py +++ b/apps/api/src/api/v1/agents.py @@ -136,6 +136,9 @@ from src.services.ai_agent_result_capture_release_decision_next_handoff import ( from src.services.ai_agent_result_capture_release_decision_input_prep import ( load_latest_ai_agent_result_capture_release_decision_input_prep, ) +from src.services.ai_agent_result_capture_release_decision_owner_response_preflight import ( + load_latest_ai_agent_result_capture_release_decision_owner_response_preflight, +) from src.services.ai_agent_result_capture_owner_promotion_review import ( load_latest_ai_agent_result_capture_owner_promotion_review, ) @@ -2424,6 +2427,36 @@ async def get_agent_result_capture_release_decision_input_prep() -> dict[str, An ) from exc +@router.get( + "/agent-result-capture-release-decision-owner-response-preflight", + response_model=dict[str, Any], + summary="取得 AI Agent result capture release decision owner response preflight", + description=( + "讀取最新已提交的 P2-143 release decision owner response preflight;" + "此端點只把 P2-141 決策輸入準備包轉成 owner response 預檢與拒收邊界," + "不把預檢視為正式收件或批准、不核發 release authorization、" + "不寫 reviewer queue、Gateway queue、receipt、result capture、learning 或 PlayBook trust," + "不送 Telegram、不呼叫 Bot API、不讀 secret、不執行 production 寫入。" + ), +) +async def get_agent_result_capture_release_decision_owner_response_preflight() -> dict[str, Any]: + """Return the latest read-only release decision owner-response preflight.""" + try: + payload = await asyncio.to_thread(load_latest_ai_agent_result_capture_release_decision_owner_response_preflight) + return redact_public_lan_topology(payload) + except FileNotFoundError as exc: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=str(exc), + ) from exc + except (json.JSONDecodeError, ValueError) as exc: + logger.error("ai_agent_result_capture_release_decision_owner_response_preflight_invalid", error=str(exc)) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="AI Agent result capture release decision owner response preflight 無效", + ) from exc + + @router.get( "/agent-owner-approved-fixture-dry-run", response_model=dict[str, Any], diff --git a/apps/api/src/services/ai_agent_result_capture_release_decision_owner_response_preflight.py b/apps/api/src/services/ai_agent_result_capture_release_decision_owner_response_preflight.py new file mode 100644 index 00000000..a3c38ada --- /dev/null +++ b/apps/api/src/services/ai_agent_result_capture_release_decision_owner_response_preflight.py @@ -0,0 +1,376 @@ +""" +AI Agent result capture release decision owner-response preflight snapshot. + +Loads the latest committed P2-143 owner-response preflight package. This module +only turns P2-141 decision input prep into read-only intake checks and rejection +guards; it never treats preflight as receipt, approval, reviewer queue write, +Gateway queue write, Telegram send, Bot API call, result capture, learning, +PlayBook trust, secret read, production write, or destructive operation. +""" + +from __future__ import annotations + +import json +import re +from pathlib import Path +from typing import Any + +from src.services.snapshot_paths import default_evaluations_dir + +_DEFAULT_EVALUATIONS_DIR = default_evaluations_dir(Path(__file__)) +_SNAPSHOT_PATTERN = "ai_agent_result_capture_release_decision_owner_response_preflight_*.json" +_SCHEMA_VERSION = "ai_agent_result_capture_release_decision_owner_response_preflight_v1" +_RUNTIME_AUTHORITY = "result_capture_release_decision_owner_response_preflight_only_no_live_write" + + +def load_latest_ai_agent_result_capture_release_decision_owner_response_preflight( + evaluations_dir: Path | None = None, +) -> dict[str, Any]: + """Load the newest committed release decision owner-response preflight.""" + directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR + candidates = sorted(directory.glob(_SNAPSHOT_PATTERN)) + if not candidates: + raise FileNotFoundError( + f"no AI Agent result capture release decision owner response preflight 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_response_intake_lanes(payload, label) + _require_validation_checks(payload, label) + _require_rejection_guards(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-143", + "next_task_id": "P2-144", + "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_decision_input_prep") or {} + expected = { + "schema_version": "ai_agent_result_capture_release_decision_input_prep_v1", + "current_task_id": "P2-141", + "next_task_id": "P2-142", + "decision_input_packet_count": 5, + "missing_input_field_count": 18, + "blocked_input_transition_count": 6, + "operator_action_count": 5, + "approval_required_subtotal": 12, + "blocked_and_critical_subtotal": 12, + } + expected.update(_zero_count_expectations()) + mismatches = _mismatches(prior, expected) + if mismatches: + raise ValueError(f"{label}: prior_decision_input_prep mismatch: {mismatches}") + if not prior.get("readiness_note"): + raise ValueError(f"{label}: prior_decision_input_prep.readiness_note is required") + + +def _require_truth(payload: dict[str, Any], label: str) -> None: + truth = payload.get("owner_response_preflight_truth") or {} + required_true = { + "p2_141_input_prep_loaded", + "p2_142_war_room_baseline_preserved", + "required_owner_fields_declared", + "required_verifier_fields_declared", + "required_rollback_fields_declared", + "required_maintenance_window_fields_declared", + "required_live_apply_fields_declared", + "redaction_contract_loaded", + "preflight_only_mode", + "no_raw_payload_required", + "rejection_policy_active", + } + missing = sorted(field for field in required_true if truth.get(field) is not True) + if missing: + raise ValueError(f"{label}: owner response preflight flags must remain true: {missing}") + + required_false = { + "owner_response_received", + "owner_response_accepted", + "owner_response_rejected", + "redacted_payload_ingested", + "owner_release_authorized", + "owner_release_approved", + "owner_review_approved", + "owner_decision_approved", + "verifier_decision_approved", + "maintenance_window_approved", + "rollback_owner_confirmed", + "post_release_verifier_ready", + "final_release_candidate_approved", + "final_release_candidate_passed", + "release_decision_passed", + "release_authorization_granted", + "release_authorization_passed", + "rollback_release_passed", + "live_apply_release_passed", + "writer_apply_enabled", + "execution_apply_enabled", + "receipt_write_enabled", + "reviewer_queue_write_enabled", + "gateway_queue_write_enabled", + "telegram_send_enabled", + "bot_api_call_enabled", + "report_receipt_write_enabled", + "result_capture_write_enabled", + "learning_write_enabled", + "playbook_trust_write_enabled", + "production_write_enabled", + "secret_read_enabled", + "destructive_operation_enabled", + } + unsafe = sorted(field for field in required_false if truth.get(field) is not False) + if unsafe: + raise ValueError(f"{label}: owner response live/send/write flags must remain false: {unsafe}") + + non_zero = sorted(field for field in _owner_response_zero_counts() if truth.get(field) != 0) + if non_zero: + raise ValueError(f"{label}: owner response live counters must remain zero: {non_zero}") + if not truth.get("truth_note"): + raise ValueError(f"{label}: owner_response_preflight_truth.truth_note is required") + + +def _require_response_intake_lanes(payload: dict[str, Any], label: str) -> None: + items = payload.get("response_intake_lanes") or [] + _require_ids( + items, + "lane_id", + { + "owner_release_response_preflight", + "verifier_response_preflight", + "rollback_owner_response_preflight", + "maintenance_window_response_preflight", + "live_apply_response_preflight", + }, + label, + "response intake lanes", + ) + for item in items: + item_id = item.get("lane_id") + expected = { + "current_task_id": "P2-143", + "target_next_task_id": "P2-144", + "intake_status": "waiting_for_external_owner_response", + "accepted": False, + "redacted_payload_ingested": False, + "runtime_write_allowed": False, + "telegram_send_allowed": False, + } + mismatches = _mismatches(item, expected) + if mismatches: + raise ValueError(f"{label}: response intake lane {item_id} mismatch: {mismatches}") + required_fields = item.get("required_fields") or [] + if not isinstance(required_fields, list) or not required_fields: + raise ValueError(f"{label}: response intake lane {item_id}.required_fields is required") + if not item.get("source_packet_id"): + raise ValueError(f"{label}: response intake lane {item_id}.source_packet_id is required") + if not item.get("preflight_summary"): + raise ValueError(f"{label}: response intake lane {item_id}.preflight_summary is required") + if not _is_redacted_sha256(item.get("evidence_hash")): + raise ValueError(f"{label}: response intake lane {item_id}.evidence_hash must be redacted sha256") + + +def _require_validation_checks(payload: dict[str, Any], label: str) -> None: + items = payload.get("intake_validation_checks") or [] + _require_count(items, 6, label, "intake validation checks") + for item in items: + item_id = item.get("check_id") + if item.get("status") not in {"waiting_for_owner_response", "not_satisfied", "blocked_by_policy"}: + raise ValueError(f"{label}: intake validation check {item_id} status is invalid") + if item.get("runtime_write_allowed") is not False: + raise ValueError(f"{label}: intake validation check {item_id} must keep runtime_write_allowed=false") + if not item.get("requirement"): + raise ValueError(f"{label}: intake validation check {item_id}.requirement is required") + + +def _require_rejection_guards(payload: dict[str, Any], label: str) -> None: + items = payload.get("rejection_guards") or [] + _require_count(items, 6, label, "rejection guards") + for item in items: + item_id = item.get("guard_id") + if item.get("status") != "active": + raise ValueError(f"{label}: rejection guard {item_id} status must remain active") + if item.get("runtime_write_allowed") is not False: + raise ValueError(f"{label}: rejection guard {item_id} must keep runtime_write_allowed=false") + if not item.get("reason"): + raise ValueError(f"{label}: rejection guard {item_id}.reason is required") + + +def _require_actions(payload: dict[str, Any], label: str) -> None: + items = payload.get("operator_actions") or [] + _require_count(items, 5, label, "operator actions") + for item in items: + item_id = str(item.get("action_id")) + if "p2_139" in item_id or "p2_140" in item_id or "p2_141" in item_id: + raise ValueError(f"{label}: operator action {item_id} must not point back to P2-139/P2-140/P2-141") + if item.get("runtime_write_allowed") is not False: + raise ValueError(f"{label}: operator action {item_id} must keep runtime_write_allowed=false") + if item.get("status") not in {"ready_for_operator_review", "approval_required"}: + raise ValueError(f"{label}: operator action {item_id} status is invalid") + if not item.get("operator_instruction"): + raise ValueError(f"{label}: operator action {item_id}.operator_instruction is required") + + +def _require_display_redaction(payload: dict[str, Any], label: str) -> None: + contract = payload.get("display_redaction_contract") or {} + expected = { + "redaction_required": True, + "raw_prompt_display_allowed": False, + "private_reasoning_display_allowed": False, + "secret_value_display_allowed": False, + "raw_runtime_payload_display_allowed": False, + "internal_collaboration_content_display_allowed": False, + } + mismatches = _mismatches(contract, expected) + if mismatches: + raise ValueError(f"{label}: display_redaction_contract mismatch: {mismatches}") + if not contract.get("frontend_display_policy"): + raise ValueError(f"{label}: display_redaction_contract.frontend_display_policy is required") + + +def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None: + rollups = payload.get("rollups") or {} + required_owner_field_count = sum(len(item.get("required_fields") or []) for item in payload.get("response_intake_lanes") or []) + expected = { + "response_intake_lane_count": len(payload.get("response_intake_lanes") or []), + "required_owner_field_count": required_owner_field_count, + "intake_validation_check_count": len(payload.get("intake_validation_checks") or []), + "rejection_guard_count": len(payload.get("rejection_guards") or []), + "operator_action_count": len(payload.get("operator_actions") or []), + "waiting_external_response_count": len(payload.get("response_intake_lanes") or []), + "approval_required_subtotal": 12, + "blocked_and_critical_subtotal": 12, + } + expected.update(_owner_response_zero_counts()) + mismatches = _mismatches(rollups, expected) + if mismatches: + raise ValueError(f"{label}: rollups mismatch: {mismatches}") + + +def _require_no_forbidden_display_terms(payload: Any, label: str) -> None: + forbidden = { + "work_window_transcript", + "internal_collaboration_transcript", + "raw_prompt", + "private_reasoning", + "chain_of_thought", + "authorization_header", + "secret_value", + "工作視窗", + "內部協作", + "原始提示詞", + "私有推理", + "原始 runtime payload", + "raw runtime payload", + "authorization header", + } + found = sorted(term for term in forbidden if _contains_term(payload, term)) + if found: + raise ValueError(f"{label}: forbidden display terms leaked: {found}") + + +def _contains_term(value: Any, term: str) -> bool: + if isinstance(value, str): + return term.lower() in value.lower() + if isinstance(value, dict): + return any(_contains_term(child, term) for child in value.values()) + if isinstance(value, list): + return any(_contains_term(child, term) for child in value) + return False + + +def _owner_response_zero_counts() -> dict[str, int]: + return { + "owner_response_received_count": 0, + "owner_response_accepted_count": 0, + "owner_response_rejected_count": 0, + "redacted_payload_ingested_count": 0, + **_zero_count_expectations(), + } + + +def _zero_count_expectations() -> dict[str, int]: + return { + "owner_release_authorized_count": 0, + "owner_release_approved_count": 0, + "owner_review_approved_count": 0, + "owner_decision_approved_count": 0, + "verifier_decision_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "final_release_candidate_approved_count": 0, + "final_release_candidate_pass_count": 0, + "release_decision_pass_count": 0, + "release_authorization_granted_count": 0, + "release_authorization_pass_count": 0, + "rollback_release_pass_count": 0, + "live_apply_release_pass_count": 0, + "writer_apply_count": 0, + "execution_apply_count": 0, + "receipt_write_count": 0, + "reviewer_queue_write_count": 0, + "gateway_queue_write_count": 0, + "telegram_send_count": 0, + "bot_api_call_count": 0, + "report_receipt_write_count": 0, + "result_capture_write_count": 0, + "learning_write_count": 0, + "playbook_trust_write_count": 0, + "production_write_count": 0, + "secret_read_count": 0, + "destructive_operation_count": 0, + } + + +def _require_ids(items: list[dict[str, Any]], field: str, expected_ids: set[str], label: str, group_name: str) -> None: + actual_ids = {str(item.get(field)) for item in items} + if actual_ids != expected_ids: + raise ValueError(f"{label}: {group_name} ids mismatch: expected={sorted(expected_ids)} actual={sorted(actual_ids)}") + + +def _require_count(items: list[Any], expected: int, label: str, group_name: str) -> None: + if len(items) != expected: + raise ValueError(f"{label}: expected {expected} {group_name}, got {len(items)}") + + +def _is_redacted_sha256(value: Any) -> bool: + return isinstance(value, str) and re.fullmatch(r"sha256:[0-9a-f]{64}", value) is not None + + +def _mismatches(payload: dict[str, Any], expected: dict[str, Any]) -> dict[str, dict[str, Any]]: + return { + key: {"expected": expected_value, "actual": payload.get(key)} + for key, expected_value in expected.items() + if payload.get(key) != expected_value + } diff --git a/apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_preflight.py b/apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_preflight.py new file mode 100644 index 00000000..fa85f386 --- /dev/null +++ b/apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_preflight.py @@ -0,0 +1,110 @@ +from __future__ import annotations + +import copy +import json +from pathlib import Path + +import pytest + +from src.services.ai_agent_result_capture_release_decision_owner_response_preflight import ( + load_latest_ai_agent_result_capture_release_decision_owner_response_preflight, +) + + +def test_load_latest_release_decision_owner_response_preflight_snapshot() -> None: + snapshot = load_latest_ai_agent_result_capture_release_decision_owner_response_preflight() + + assert snapshot["schema_version"] == "ai_agent_result_capture_release_decision_owner_response_preflight_v1" + assert snapshot["program_status"]["current_task_id"] == "P2-143" + assert snapshot["program_status"]["next_task_id"] == "P2-144" + assert snapshot["program_status"]["overall_completion_percent"] == 100 + assert snapshot["program_status"]["runtime_authority"] == ( + "result_capture_release_decision_owner_response_preflight_only_no_live_write" + ) + + rollups = snapshot["rollups"] + assert rollups["response_intake_lane_count"] == 5 + assert rollups["required_owner_field_count"] == 18 + assert rollups["intake_validation_check_count"] == 6 + assert rollups["rejection_guard_count"] == 6 + assert rollups["operator_action_count"] == 5 + assert rollups["waiting_external_response_count"] == 5 + assert rollups["owner_response_received_count"] == 0 + assert rollups["owner_response_accepted_count"] == 0 + assert rollups["redacted_payload_ingested_count"] == 0 + assert rollups["reviewer_queue_write_count"] == 0 + assert rollups["gateway_queue_write_count"] == 0 + assert rollups["telegram_send_count"] == 0 + assert rollups["bot_api_call_count"] == 0 + assert rollups["production_write_count"] == 0 + + +def test_owner_response_preflight_truth_keeps_all_runtime_gates_closed() -> None: + snapshot = load_latest_ai_agent_result_capture_release_decision_owner_response_preflight() + truth = snapshot["owner_response_preflight_truth"] + + assert truth["p2_141_input_prep_loaded"] is True + assert truth["p2_142_war_room_baseline_preserved"] is True + assert truth["preflight_only_mode"] is True + assert truth["rejection_policy_active"] is True + assert truth["owner_response_received"] is False + assert truth["owner_response_accepted"] is False + assert truth["redacted_payload_ingested"] is False + assert truth["release_authorization_granted"] is False + assert truth["reviewer_queue_write_enabled"] is False + assert truth["gateway_queue_write_enabled"] is False + assert truth["telegram_send_enabled"] is False + assert truth["production_write_enabled"] is False + assert truth["secret_read_enabled"] is False + assert truth["destructive_operation_enabled"] is False + + +def test_rejects_missing_response_intake_lane(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_decision_owner_response_preflight()) + snapshot["response_intake_lanes"] = snapshot["response_intake_lanes"][:-1] + snapshot["rollups"]["response_intake_lane_count"] = 4 + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="response intake lanes ids mismatch"): + load_latest_ai_agent_result_capture_release_decision_owner_response_preflight(tmp_path) + + +def test_rejects_owner_response_received_drift(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_decision_owner_response_preflight()) + snapshot["owner_response_preflight_truth"]["owner_response_received"] = True + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="flags must remain false"): + load_latest_ai_agent_result_capture_release_decision_owner_response_preflight(tmp_path) + + +def test_rejects_gateway_write_drift(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_decision_owner_response_preflight()) + snapshot["rollups"]["gateway_queue_write_count"] = 1 + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="rollups mismatch"): + load_latest_ai_agent_result_capture_release_decision_owner_response_preflight(tmp_path) + + +def test_rejects_forbidden_display_terms(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_decision_owner_response_preflight()) + snapshot["operator_actions"][0]["operator_instruction"] = "不要顯示 raw_prompt" + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="forbidden display terms leaked"): + load_latest_ai_agent_result_capture_release_decision_owner_response_preflight(tmp_path) + + +def test_rejects_chinese_forbidden_display_terms(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_decision_owner_response_preflight()) + snapshot["operator_actions"][0]["operator_instruction"] = "不要顯示工作視窗內容" + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="forbidden display terms leaked"): + load_latest_ai_agent_result_capture_release_decision_owner_response_preflight(tmp_path) + + +def _write_snapshot(directory: Path, payload: dict) -> None: + path = directory / "ai_agent_result_capture_release_decision_owner_response_preflight_2099-01-01.json" + path.write_text(json.dumps(payload, ensure_ascii=False), encoding="utf-8") diff --git a/apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_preflight_api.py b/apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_preflight_api.py new file mode 100644 index 00000000..5fbce080 --- /dev/null +++ b/apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_preflight_api.py @@ -0,0 +1,49 @@ +from __future__ import annotations + +from fastapi.testclient import TestClient + +from src.main import app + + +def test_release_decision_owner_response_preflight_endpoint() -> None: + client = TestClient(app) + + response = client.get("/api/v1/agents/agent-result-capture-release-decision-owner-response-preflight") + + assert response.status_code == 200 + payload = response.json() + assert payload["schema_version"] == "ai_agent_result_capture_release_decision_owner_response_preflight_v1" + assert payload["program_status"]["current_task_id"] == "P2-143" + assert payload["program_status"]["next_task_id"] == "P2-144" + assert payload["program_status"]["overall_completion_percent"] == 100 + assert payload["program_status"]["runtime_authority"] == ( + "result_capture_release_decision_owner_response_preflight_only_no_live_write" + ) + assert payload["prior_decision_input_prep"]["schema_version"] == ( + "ai_agent_result_capture_release_decision_input_prep_v1" + ) + assert payload["prior_decision_input_prep"]["next_task_id"] == "P2-142" + assert payload["rollups"]["response_intake_lane_count"] == 5 + assert payload["rollups"]["required_owner_field_count"] == 18 + assert payload["rollups"]["intake_validation_check_count"] == 6 + assert payload["rollups"]["rejection_guard_count"] == 6 + assert payload["rollups"]["operator_action_count"] == 5 + assert payload["rollups"]["owner_response_received_count"] == 0 + assert payload["rollups"]["owner_response_accepted_count"] == 0 + assert payload["rollups"]["redacted_payload_ingested_count"] == 0 + assert payload["rollups"]["reviewer_queue_write_count"] == 0 + assert payload["rollups"]["gateway_queue_write_count"] == 0 + assert payload["rollups"]["telegram_send_count"] == 0 + assert payload["rollups"]["bot_api_call_count"] == 0 + assert payload["rollups"]["production_write_count"] == 0 + + owner_lane = payload["response_intake_lanes"][0] + assert owner_lane["lane_id"] == "owner_release_response_preflight" + assert owner_lane["required_fields"] == [ + "owner_role_team", + "owner_decision", + "decision_reason", + "affected_scope", + "redacted_evidence_refs", + "followup_owner", + ] diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 1c4a65ec..a47acbaa 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -6293,6 +6293,43 @@ "telegramSendAllowed": "Telegram 發送允許={value}" } }, + "resultCaptureReleaseDecisionOwnerResponsePreflight": { + "title": "P2-143 Owner response 預檢與拒收邊界", + "source": "產生 {generated};目前 {current};下一步 {next}", + "priorTitle": "P2-141 決策輸入基線", + "truthTitle": "Owner response 預檢真相", + "laneTitle": "回覆預檢 lane", + "guardTitle": "拒收規則", + "actionTitle": "操作員預檢事項", + "metrics": { + "overall": "完成度", + "lanes": "預檢 lane", + "requiredFields": "必填欄位", + "validationChecks": "驗證檢查", + "rejectionGuards": "拒收規則", + "actions": "操作選項", + "waiting": "等待回覆", + "received": "已收 / 已接受", + "liveWrites": "正式寫入 / 發送" + }, + "flags": { + "p2Loaded": "已載入 P2-141={value}", + "preflightOnly": "只做預檢={value}", + "rejectionPolicy": "拒收規則啟用={value}" + }, + "labels": { + "priorCurrent": "上一關目前={value}", + "priorNext": "上一關下一步={value}", + "ownerReceived": "owner 回覆收件={value}", + "redactedPayload": "遮罩 payload 納入={value}", + "gatewayWrites": "Gateway 寫入={value}", + "telegramSends": "Telegram 送出={value}", + "productionWrites": "正式寫入={value}", + "requiredFields": "必填欄位={value}", + "accepted": "已接受={value}", + "runtimeWriteAllowed": "runtime 寫入允許={value}" + } + }, "warRoom": { "title": "12-Agent War Room 作戰室", "source": "產生 {generated};目前 {current};下一步 {next}", diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 1c4a65ec..a47acbaa 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -6293,6 +6293,43 @@ "telegramSendAllowed": "Telegram 發送允許={value}" } }, + "resultCaptureReleaseDecisionOwnerResponsePreflight": { + "title": "P2-143 Owner response 預檢與拒收邊界", + "source": "產生 {generated};目前 {current};下一步 {next}", + "priorTitle": "P2-141 決策輸入基線", + "truthTitle": "Owner response 預檢真相", + "laneTitle": "回覆預檢 lane", + "guardTitle": "拒收規則", + "actionTitle": "操作員預檢事項", + "metrics": { + "overall": "完成度", + "lanes": "預檢 lane", + "requiredFields": "必填欄位", + "validationChecks": "驗證檢查", + "rejectionGuards": "拒收規則", + "actions": "操作選項", + "waiting": "等待回覆", + "received": "已收 / 已接受", + "liveWrites": "正式寫入 / 發送" + }, + "flags": { + "p2Loaded": "已載入 P2-141={value}", + "preflightOnly": "只做預檢={value}", + "rejectionPolicy": "拒收規則啟用={value}" + }, + "labels": { + "priorCurrent": "上一關目前={value}", + "priorNext": "上一關下一步={value}", + "ownerReceived": "owner 回覆收件={value}", + "redactedPayload": "遮罩 payload 納入={value}", + "gatewayWrites": "Gateway 寫入={value}", + "telegramSends": "Telegram 送出={value}", + "productionWrites": "正式寫入={value}", + "requiredFields": "必填欄位={value}", + "accepted": "已接受={value}", + "runtimeWriteAllowed": "runtime 寫入允許={value}" + } + }, "warRoom": { "title": "12-Agent War Room 作戰室", "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 cf44c616..51d2c2ed 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 @@ -91,6 +91,7 @@ import { type AiAgentResultCaptureReleaseDecisionReadbackSnapshot, type AiAgentResultCaptureReleaseDecisionNextHandoffSnapshot, type AiAgentResultCaptureReleaseDecisionInputPrepSnapshot, + type AiAgentResultCaptureReleaseDecisionOwnerResponsePreflightSnapshot, type AiAgentResultCaptureReleaseVerifierPreflightGateSnapshot, type AiAgentResultCaptureReleaseVerifierOwnerReviewPacketSnapshot, type AiAgentResultCaptureWriterImplementationReviewSnapshot, @@ -515,6 +516,7 @@ export function AutomationInventoryTab() { const [resultCaptureReleaseDecisionReadback, setResultCaptureReleaseDecisionReadback] = useState(null) const [resultCaptureReleaseDecisionNextHandoff, setResultCaptureReleaseDecisionNextHandoff] = useState(null) const [resultCaptureReleaseDecisionInputPrep, setResultCaptureReleaseDecisionInputPrep] = useState(null) + const [resultCaptureReleaseDecisionOwnerResponsePreflight, setResultCaptureReleaseDecisionOwnerResponsePreflight] = useState(null) const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState(null) const [ownerDryRunPackage, setOwnerDryRunPackage] = useState(null) const [hostStatefulInventory, setHostStatefulInventory] = useState(null) @@ -594,6 +596,7 @@ export function AutomationInventoryTab() { apiClient.getAiAgentResultCaptureReleaseDecisionReadback(), apiClient.getAiAgentResultCaptureReleaseDecisionNextHandoff(), apiClient.getAiAgentResultCaptureReleaseDecisionInputPrep(), + apiClient.getAiAgentResultCaptureReleaseDecisionOwnerResponsePreflight(), apiClient.getAiAgentReportTruthActionabilityReview(), apiClient.getAiAgentOwnerApprovedFixtureDryRun(), apiClient.getAiAgentHostStatefulVersionInventory(), @@ -672,6 +675,7 @@ export function AutomationInventoryTab() { resultCaptureReleaseDecisionReadbackResult, resultCaptureReleaseDecisionNextHandoffResult, resultCaptureReleaseDecisionInputPrepResult, + resultCaptureReleaseDecisionOwnerResponsePreflightResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -747,6 +751,7 @@ export function AutomationInventoryTab() { setResultCaptureReleaseDecisionReadback(resultCaptureReleaseDecisionReadbackResult.status === 'fulfilled' ? resultCaptureReleaseDecisionReadbackResult.value : null) setResultCaptureReleaseDecisionNextHandoff(resultCaptureReleaseDecisionNextHandoffResult.status === 'fulfilled' ? resultCaptureReleaseDecisionNextHandoffResult.value : null) setResultCaptureReleaseDecisionInputPrep(resultCaptureReleaseDecisionInputPrepResult.status === 'fulfilled' ? resultCaptureReleaseDecisionInputPrepResult.value : null) + setResultCaptureReleaseDecisionOwnerResponsePreflight(resultCaptureReleaseDecisionOwnerResponsePreflightResult.status === 'fulfilled' ? resultCaptureReleaseDecisionOwnerResponsePreflightResult.value : null) setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null) setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null) setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null) @@ -820,6 +825,7 @@ export function AutomationInventoryTab() { resultCaptureReleaseDecisionReadbackResult, resultCaptureReleaseDecisionNextHandoffResult, resultCaptureReleaseDecisionInputPrepResult, + resultCaptureReleaseDecisionOwnerResponsePreflightResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -2075,7 +2081,7 @@ export function AutomationInventoryTab() { ) } - if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !warRoom || !proactiveOperations || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportAutomationReview || !reportStatusBoard || !reportRuntimeReadiness || !reportRuntimeDryRun || !reportRuntimeFixtureReadback || !runtimeWorkerShadowGate || !operationPermissionModel || !candidateOperationDryRunEvidence || !taskResultAuditTrail || !matchedPlaybookLearningGap || !criticReviewerResultCapture || !ownerApprovedResultCaptureDryRun || !ownerApprovedResultCaptureReadback || !runtimeReadbackApprovalPackage || !runtimeReadbackImplementationReview || !reportLiveDeliveryApprovalPackage || !runtimeReadbackFixtureApproval || !runtimeReadbackPromotionGate || !ownerApprovedFixturePromotionGate || !canonicalRuntimeReadbackOwnerAcceptance || !failureReceiptNoSendReplay || !reviewerQueueNoWriteReadback || !resultCaptureNoWriteReadback || !resultCapturePromotionApprovalGate || !ownerApprovedResultCapturePromotionDryRun || !resultCaptureWriteGateReview || !resultCaptureWriterImplementationReview || !resultCaptureWriterDryRunFixture || !resultCaptureWriterDryRunReadback || !resultCaptureOwnerPromotionReview || !resultCaptureOwnerApprovedExecutionRehearsal || !resultCaptureOwnerAcceptanceMaintenanceGate || !resultCaptureOwnerAcceptanceReadbackPreflightHold || !resultCaptureOwnerApprovedPreflightReleasePackage || !resultCaptureOwnerApprovedReleaseReadinessReadback || !resultCaptureOwnerReleaseApprovalGate || !resultCapturePostReleaseVerifierRollbackGate || !resultCaptureFinalReleaseCandidateReadback || !resultCaptureReleaseAuthorizationHold || !resultCaptureReleaseAuthorizationReadbackGate || !resultCaptureReleaseVerifierPreflightGate || !resultCaptureReleaseVerifierOwnerReviewPacket || !resultCaptureReleaseDecisionHold || !resultCaptureReleaseDecisionReadback || !resultCaptureReleaseDecisionNextHandoff || !resultCaptureReleaseDecisionInputPrep || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { + if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !warRoom || !proactiveOperations || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportAutomationReview || !reportStatusBoard || !reportRuntimeReadiness || !reportRuntimeDryRun || !reportRuntimeFixtureReadback || !runtimeWorkerShadowGate || !operationPermissionModel || !candidateOperationDryRunEvidence || !taskResultAuditTrail || !matchedPlaybookLearningGap || !criticReviewerResultCapture || !ownerApprovedResultCaptureDryRun || !ownerApprovedResultCaptureReadback || !runtimeReadbackApprovalPackage || !runtimeReadbackImplementationReview || !reportLiveDeliveryApprovalPackage || !runtimeReadbackFixtureApproval || !runtimeReadbackPromotionGate || !ownerApprovedFixturePromotionGate || !canonicalRuntimeReadbackOwnerAcceptance || !failureReceiptNoSendReplay || !reviewerQueueNoWriteReadback || !resultCaptureNoWriteReadback || !resultCapturePromotionApprovalGate || !ownerApprovedResultCapturePromotionDryRun || !resultCaptureWriteGateReview || !resultCaptureWriterImplementationReview || !resultCaptureWriterDryRunFixture || !resultCaptureWriterDryRunReadback || !resultCaptureOwnerPromotionReview || !resultCaptureOwnerApprovedExecutionRehearsal || !resultCaptureOwnerAcceptanceMaintenanceGate || !resultCaptureOwnerAcceptanceReadbackPreflightHold || !resultCaptureOwnerApprovedPreflightReleasePackage || !resultCaptureOwnerApprovedReleaseReadinessReadback || !resultCaptureOwnerReleaseApprovalGate || !resultCapturePostReleaseVerifierRollbackGate || !resultCaptureFinalReleaseCandidateReadback || !resultCaptureReleaseAuthorizationHold || !resultCaptureReleaseAuthorizationReadbackGate || !resultCaptureReleaseVerifierPreflightGate || !resultCaptureReleaseVerifierOwnerReviewPacket || !resultCaptureReleaseDecisionHold || !resultCaptureReleaseDecisionReadback || !resultCaptureReleaseDecisionNextHandoff || !resultCaptureReleaseDecisionInputPrep || !resultCaptureReleaseDecisionOwnerResponsePreflight || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { return (
@@ -3482,6 +3488,32 @@ export function AutomationInventoryTab() { + resultCaptureReleaseDecisionInputPrep.rollups.playbook_trust_write_count + resultCaptureReleaseDecisionInputPrep.rollups.production_write_count ) + const resultCaptureReleaseDecisionOwnerResponsePreflightOverall = resultCaptureReleaseDecisionOwnerResponsePreflight.program_status.overall_completion_percent + const resultCaptureReleaseDecisionOwnerResponseLanes = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.response_intake_lane_count + const resultCaptureReleaseDecisionOwnerResponseFields = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.required_owner_field_count + const resultCaptureReleaseDecisionOwnerResponseChecks = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.intake_validation_check_count + const resultCaptureReleaseDecisionOwnerResponseGuards = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.rejection_guard_count + const resultCaptureReleaseDecisionOwnerResponseActions = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.operator_action_count + const resultCaptureReleaseDecisionOwnerResponseWaiting = resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.waiting_external_response_count + const resultCaptureReleaseDecisionOwnerResponseReceived = ( + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.owner_response_received_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.owner_response_accepted_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.redacted_payload_ingested_count + ) + const resultCaptureReleaseDecisionOwnerResponseLiveWrites = ( + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.writer_apply_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.execution_apply_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.receipt_write_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.reviewer_queue_write_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.gateway_queue_write_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.telegram_send_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.bot_api_call_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.report_receipt_write_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.result_capture_write_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.learning_write_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.playbook_trust_write_count + + resultCaptureReleaseDecisionOwnerResponsePreflight.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 @@ -8187,6 +8219,129 @@ export function AutomationInventoryTab() {
+
+
+
+ + + {t('resultCaptureReleaseDecisionOwnerResponsePreflight.title')} + +
+ +
+ +
+ } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> +
+ +
+
+ {t('resultCaptureReleaseDecisionOwnerResponsePreflight.priorTitle')} +

+ {resultCaptureReleaseDecisionOwnerResponsePreflight.prior_decision_input_prep.readiness_note} +

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

+ {resultCaptureReleaseDecisionOwnerResponsePreflight.owner_response_preflight_truth.truth_note} +

+
+ + + + + + + + +
+
+
+ + {t('resultCaptureReleaseDecisionOwnerResponsePreflight.laneTitle')} +
+ {resultCaptureReleaseDecisionOwnerResponsePreflight.response_intake_lanes.slice(0, 5).map(lane => ( +
+
+ + {lane.display_name} + + +
+ + {lane.preflight_summary} + +
+ + + + + +
+
+ ))} +
+ +
+ {resultCaptureReleaseDecisionOwnerResponsePreflight.rejection_guards.slice(0, 6).map(guard => ( +
+ {t('resultCaptureReleaseDecisionOwnerResponsePreflight.guardTitle')} + + {guard.guard_id} + + + {guard.reason} + + +
+ ))} +
+ + {t('resultCaptureReleaseDecisionOwnerResponsePreflight.actionTitle')} +
+ {resultCaptureReleaseDecisionOwnerResponsePreflight.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 44028894..6034e0eb 100644 --- a/apps/web/src/lib/api-client.ts +++ b/apps/web/src/lib/api-client.ts @@ -619,6 +619,11 @@ export const apiClient = { return handleResponse(res) }, + async getAiAgentResultCaptureReleaseDecisionOwnerResponsePreflight() { + const res = await fetch(`${API_BASE_URL}/agents/agent-result-capture-release-decision-owner-response-preflight`) + return handleResponse(res) + }, + async getAiAgentOwnerApprovedFixtureDryRun() { const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`) return handleResponse(res) @@ -1295,8 +1300,8 @@ export interface AiAgent12AgentWarRoomSnapshot { program_status: { overall_completion_percent: number current_priority: 'P0' | 'P1' | 'P2' | 'P3' - current_task_id: 'P2-142' - next_task_id: 'P2-143' + current_task_id: 'P2-143' + next_task_id: 'P2-144' read_only_mode: true runtime_authority: '12_agent_war_room_read_only_no_live_write' status_note: string @@ -9921,6 +9926,122 @@ export interface AiAgentResultCaptureReleaseDecisionInputPrepSnapshot { } } +interface AiAgentReleaseDecisionOwnerResponseIntakeLane { + lane_id: string + display_name: string + source_packet_id: string + owner_agent: string + current_task_id: string + target_next_task_id: string + intake_status: string + required_fields: string[] + preflight_summary: string + accepted: boolean + redacted_payload_ingested: boolean + runtime_write_allowed: boolean + telegram_send_allowed: boolean + evidence_hash?: string +} + +export interface AiAgentResultCaptureReleaseDecisionOwnerResponsePreflightSnapshot { + schema_version: 'ai_agent_result_capture_release_decision_owner_response_preflight_v1' + generated_at: string + program_status: { + overall_completion_percent: number + current_priority: 'P0' | 'P1' | 'P2' | 'P3' + current_task_id: 'P2-142' + next_task_id: 'P2-143' + read_only_mode: true + runtime_authority: 'result_capture_release_decision_owner_response_preflight_only_no_live_write' + status_note: string + } + source_refs: string[] + prior_decision_input_prep: AiAgentReleaseDecisionNextHandoffZeroCounts & { + schema_version: string + current_task_id: string + next_task_id: string + decision_input_packet_count: number + missing_input_field_count: number + blocked_input_transition_count: number + operator_action_count: number + approval_required_subtotal: number + blocked_and_critical_subtotal: number + readiness_note: string + } + owner_response_preflight_truth: AiAgentReleaseDecisionNextHandoffZeroCounts & { + p2_141_input_prep_loaded: boolean + p2_142_war_room_baseline_preserved: boolean + required_owner_fields_declared: boolean + required_verifier_fields_declared: boolean + required_rollback_fields_declared: boolean + required_maintenance_window_fields_declared: boolean + required_live_apply_fields_declared: boolean + redaction_contract_loaded: boolean + preflight_only_mode: boolean + no_raw_payload_required: boolean + rejection_policy_active: boolean + truth_note: string + owner_response_received: boolean + owner_response_accepted: boolean + owner_response_rejected: boolean + redacted_payload_ingested: boolean + owner_response_received_count: number + owner_response_accepted_count: number + owner_response_rejected_count: number + redacted_payload_ingested_count: number + release_authorization_granted: boolean + gateway_queue_write_enabled: boolean + telegram_send_enabled: boolean + result_capture_write_enabled: boolean + learning_write_enabled: boolean + playbook_trust_write_enabled: boolean + production_write_enabled: boolean + } + response_intake_lanes: AiAgentReleaseDecisionOwnerResponseIntakeLane[] + intake_validation_checks: { + check_id: string + status: string + requirement: string + runtime_write_allowed: boolean + }[] + rejection_guards: { + guard_id: string + status: string + reason: string + runtime_write_allowed: boolean + }[] + operator_actions: { + action_id: string + owner_agent: string + status: string + operator_instruction: string + runtime_write_allowed: boolean + }[] + display_redaction_contract: { + redaction_required: boolean + raw_prompt_display_allowed: boolean + private_reasoning_display_allowed: boolean + secret_value_display_allowed: boolean + raw_runtime_payload_display_allowed: boolean + internal_collaboration_content_display_allowed: boolean + frontend_display_policy: string + } + rollups: AiAgentReleaseDecisionNextHandoffZeroCounts & { + response_intake_lane_count: number + required_owner_field_count: number + intake_validation_check_count: number + rejection_guard_count: number + operator_action_count: number + waiting_external_response_count: number + approval_required_subtotal: number + blocked_and_critical_subtotal: number + owner_response_received_count: number + owner_response_accepted_count: number + owner_response_rejected_count: number + redacted_payload_ingested_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 58887b09..f9a89da1 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,35 @@ +## 2026-06-14|P2-143 Owner response 預檢與拒收邊界本地完成 + +**背景**:`5de4b3f3 feat(governance): 新增 12-Agent War Room 讀回` 已先進入 `gitea/main`,並佔用 `P2-142`;本輪已非破壞性整合該 commit,將 owner response 預檢調整為 `P2-143 -> P2-144`,避免與 War Room 撞號。P2-143 只承接 P2-141 的 decision input prep 與 P2-142 War Room 基線,建立 owner response 進入前的預檢與拒收邊界,不代表正式收件、批准或 runtime 授權。 + +**完成項目**: +- 新增 `ai_agent_result_capture_release_decision_owner_response_preflight_v1` committed snapshot、service guard、API endpoint `GET /api/v1/agents/agent-result-capture-release-decision-owner-response-preflight`、API/service tests、API client 型別與治理頁 P2-143 區塊。 +- P2-143 snapshot 固定 response intake lane `5`、required owner field `18`、intake validation check `6`、rejection guard `6`、operator action `5`、waiting external response `5`。 +- owner response received / accepted / rejected、redacted payload ingested、reviewer queue write、Gateway queue write、Telegram send、Bot API call、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 全部維持 `0`。 +- Governance automation inventory 頁新增 P2-143 卡片,顯示預檢 lane、必填欄位、拒收規則、操作員下一步與 Gateway / Telegram / production write `0`;同時保留 P2-142 War Room 讀回,不把兩個關卡混成同一任務。 + +**本地驗證**: +- JSON parse:P2-143 snapshot、`zh-TW.json`、`en.json` 通過。 +- Python 編譯:P2-143 loader 與 `agents.py` 通過。 +- API/service pytest:P2-142 War Room + P2-139 / P2-140 / P2-141 / P2-143 release decision chain `37 passed`。 +- Web typecheck:`pnpm --filter @awoooi/web typecheck` 通過。 +- Guard:`SOURCE_CONTROL_OWNER_RESPONSE_GUARD_OK`、`SECURITY_MIRROR_PROGRESS_GUARD_OK`、`DOC_SECRET_SANITY_OK scanned_files=806`、`git diff --check` 通過。 +- P2-143 snapshot / messages 禁用外露值掃描:`forbidden_value_hits=0`;`zh-TW` / `en` 維持繁中鏡像一致。 + +**安全邊界**: +- P2-143 仍只是 owner response preflight;不得把預檢、UI 可見、AwoooP approval、War Room 可見、CD success 或 smoke pass 解讀成 owner response received / accepted、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、result capture write、learning write、PlayBook trust write、production write、secret read 或 destructive operation。 +- 本輪沒有 SSH 修改主機、Nginx reload、Docker restart、firewall 變更、K8s live write、active scan、secret 明文收集、force push 或 destructive git。 + +**完成度**: +- P2-143 owner response 預檢 local slice:`100%`。 +- P2-143 production verification:`0%`。 +- P2-142 War Room production verification:deploy marker `1a2c9e36` 已存在,production API / desktop / mobile smoke 仍待補驗。 +- active runtime gate、Telegram 實發、reviewer / Gateway queue write、production write 仍維持 `0`。 + +**下一步**: +- 推送 P2-143 feature commit,等待 Gitea code-review / CD;deploy marker 生效後執行 production API readback、desktop / mobile smoke 與 in-app browser sanity。 +- 正式驗證通過後,`P2-144` 承接 owner response readback,只讀讀回預檢結果;仍不得開啟 runtime writer、Telegram 實發或 production target 寫入。 + ## 2026-06-14|P2-142 12-Agent War Room 本地完成 **背景**:統帥批准以 12 位 Agent 一起推進工作;本輪把 12 個邏輯工位與兩批次只讀審查產品化,讓治理頁能讀回每位 Agent 的工作量、風險層級、阻擋項、需批准數、報告 cadence、Telegram 邊界與 redaction 狀態。此段不代表 runtime writer、Telegram send、Bot API、production write、SDK 安裝或付費 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 10b5b290..471e6a13 100644 --- a/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md +++ b/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md @@ -12,9 +12,10 @@ | 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-141 已完成只讀證據面、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、final release candidate readback、release authorization hold / readback gate、release verifier preflight / owner review packet、release decision hold / readback、release decision next handoff 與 release decision input prep;P2-141 基線與 S4.9 owner release packet 補強皆已正式驗證,固定 5 個 decision input packet、18 個 missing input field、6 個 blocked input transition 與 5 個 operator action,並把 P2-140 下一關交接轉成 owner / verifier / rollback / maintenance / live-apply 五類決策輸入準備包;owner release packet 已補 S4.9 owner role / team、decision、decision reason、affected scope、redacted evidence refs、followup owner。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_release_decision_input_prep_v1`、`GET /api/v1/agents/agent-result-capture-release-decision-input-prep`、feature commit `ee5bf500`、deploy marker `306657fd`、Gitea code-review `2954` / CD `2953` success、P2-141 基線正式 API readback、desktop / mobile smoke;S4.9 補強 commit `77515bbe`、deploy marker `a1ad68b9`、Gitea code-review `2956` / CD `2955` success、正式 API readback missing input field `18`、owner 六欄位、desktop / mobile smoke、in-app browser smoke;本地 API/service regression `15 passed`、JSON parse、Python compile、i18n key mirror `11864`、Web typecheck、guard 與 doc secret sanity 通過;治理頁 P2-141 區塊、禁用外露字串 `0`、水平溢位 `0`、內容區危險控制 `0`、console error `0`、HTTP 4xx/5xx `0`;MASTER §3.2.1b / §3.2.1d / §3.4.3 | +| OpenClaw / Hermes / NemoTron 主動溝通、學習與成長證據 | 100% | P2-401A 到 P2-143 已完成只讀證據面、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、final release candidate readback、release authorization hold / readback gate、release verifier preflight / owner review packet、release decision hold / readback、release decision next handoff、release decision input prep、12-Agent War Room 與 owner response 預檢;P2-141 基線與 S4.9 owner release packet 補強皆已正式驗證,P2-142 已建立 12-Agent War Room 只讀回收基線,P2-143 已把 owner / verifier / rollback / maintenance / live-apply 五類外部回覆入口轉成預檢與拒收邊界。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_release_decision_owner_response_preflight_v1`、`GET /api/v1/agents/agent-result-capture-release-decision-owner-response-preflight`、`docs/evaluations/ai_agent_result_capture_release_decision_owner_response_preflight_2026-06-14.json`、5 個回覆入口 lane、18 個 owner 必填欄位、6 個 intake validation check、6 個 rejection guard、5 個 operator action、等待外部回覆 `5`、正式寫入 / 發送 `0`;P2-142 feature commit `5de4b3f3`、deploy marker `1a2c9e36` 已作為本地承接基準但 production smoke 仍待補;P2-143 本地 API/service regression `37 passed`、JSON parse、Python compile、Web typecheck、guard、doc secret sanity 與禁用值掃描通過;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 | | 12-Agent War Room 編組 | 72% | 12 個邏輯工位與分批派工規則已建立;OpenClaw / Hermes / NemoTron / SRE / Security / DevOps / Data/DR / Supply Chain / Product/UI / QA / Market / Telegram 共 12 份只讀審查已回收;已建立 schema / committed snapshot / API / tests / governance UI 區塊;runtime writer、Telegram send、Bot API、production write 仍未批准 | `ai_agent_12_agent_war_room_v1`、`docs/evaluations/ai_agent_12_agent_war_room_2026-06-14.json`、`GET /api/v1/agents/agent-12-agent-war-room`、`/zh-TW/governance?tab=automation-inventory`、12 份 Codex sub-agent 只讀回饋 | +| Owner response 預檢與拒收邊界 | 100% | P2-143 本地完成;承接 P2-141 input prep 與 P2-142 War Room,只建立 owner / verifier / rollback / maintenance / live-apply 五類外部回覆的 intake 預檢、必填欄位與拒收規則;正式 owner response 尚未收到、未接受、未寫入 | `ai_agent_result_capture_release_decision_owner_response_preflight_v1`、`GET /api/v1/agents/agent-result-capture-release-decision-owner-response-preflight`、5 個 response intake lane、18 個 required owner field、6 個 validation check、6 個 rejection guard、5 個 operator action;owner response received / accepted / redacted payload / reviewer queue / Gateway / Telegram / Bot API / production write / secret read / destructive operation 全為 `0` | | 本工作清單與分析報告 | 100% | 已完成 | 本 MD 文件 | ### 2026-06-14 08:44 狀態同步 @@ -159,13 +160,22 @@ - Desktop `1440x1000`、mobile `390x844` 與 in-app browser smoke 均確認 P2-141、P2-142、缺欄位 `18`、Gateway / Telegram / 正式寫入 `0` 可見;禁用外露字串 `0`、水平溢位 `0`、危險按鈕 `0`、console error `0`、HTTP 4xx/5xx `0`。 - P2-141 S4.9 production verification 已由 `0%` 更新為 `100%`;active runtime gate、Telegram 實發、reviewer / Gateway queue write、production write 仍維持 `0`。已可由 `P2-142` 承接下一個只讀關卡。 +### 2026-06-14 14:20 狀態同步 + +- `P2-143` owner response 預檢與拒收邊界已本地完成:新增 `ai_agent_result_capture_release_decision_owner_response_preflight_v1`、`GET /api/v1/agents/agent-result-capture-release-decision-owner-response-preflight`、治理頁 P2-143 區塊與繁中 UI 文案。 +- P2-143 站在 `5de4b3f3` P2-142 12-Agent War Room 與 deploy marker `1a2c9e36` 之後,不重複占用 P2-142;P2-142 production smoke 仍需獨立補驗,P2-143 正式部署與 production readback 也仍待 Gitea CD 完成後補驗。 +- P2-143 固定 5 個 response intake lane、18 個 required owner field、6 個 intake validation check、6 個 rejection guard、5 個 operator action、5 個 waiting external response;owner response received、accepted、rejected、redacted payload ingested、reviewer queue、Gateway queue、Telegram send、Bot API call、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 全部 `0 / false`。 +- 本地證據:P2-142 War Room + P2-139 / P2-140 / P2-141 / P2-143 API/service regression `37 passed`、JSON parse、Python compile、Web typecheck、source-control owner response guard、security mirror progress guard、doc secret sanity、禁用值掃描 `0` 與 diff check 通過。 +- 前端只顯示 committed snapshot、欄位需求、拒收規則、待外部 owner / verifier / rollback / maintenance / live-apply 回覆狀態與 `0` 寫入邊界;不得顯示內部協作內容、未遮罩 runtime 資料、敏感值或工作溝通原文。 +- P2-143 本地完成度 `100%`;production verification `0%`;active runtime gate、Telegram 實發、reviewer / Gateway queue write、production write 仍維持 `0`。真正下一步是推送後補 P2-142 / P2-143 production API 與 desktop / mobile smoke,再由 `P2-144` 承接 owner response readback。 + AI Agent 自動化工作包目前完成度:**99.8%**。本工作清單文件本身完成度:**100%**。 三 Agent 佈建布局目前完成度:**45%**。第一波已完成只讀 schema / snapshot / API / 測試 / 報告,第二波已接入治理頁自動化盤點 UI;正式 runtime 佈署、Telegram E2E 發送與 AgentSession 工作流仍需逐項 gate。 -三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。P2-403A 到 P2-142 已把互動證據、報表治理、runtime readback、reviewer / result capture / writer gates、no-write readback、promotion review、writer implementation review、writer dry-run fixture、writer dry-run readback、owner promotion execution gate、owner-approved execution rehearsal、owner acceptance / maintenance window gate、owner acceptance readback / preflight hold、owner-approved preflight release package、owner-approved release readiness readback、owner release approval gate、post-release verifier / rollback gate、final release candidate readback、release authorization hold、release authorization readback gate、release verifier preflight gate、release verifier owner review packet、release decision hold、release decision readback、release decision next handoff、release decision input prep 與 12-Agent War Room 固定成可驗證證據。P2-141 基線已由 feature commit `ee5bf500` 與 deploy marker `306657fd` 正式驗證,S4.9 owner 欄位補強已由 commit `77515bbe` 與 deploy marker `a1ad68b9` 正式驗證;P2-142 已本地完成,正式驗證後才可進入 P2-143。目前 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-142 正式部署驗證,再由 `P2-143` 承接只讀關卡;不得開啟 runtime writer、Gateway queue、Telegram send、Bot API 或 production write。 +三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。P2-403A 到 P2-143 已把互動證據、報表治理、runtime readback、reviewer / result capture / writer gates、no-write readback、promotion review、writer implementation review、writer dry-run fixture、writer dry-run readback、owner promotion execution gate、owner-approved execution rehearsal、owner acceptance / maintenance window gate、owner acceptance readback / preflight hold、owner-approved preflight release package、owner-approved release readiness readback、owner release approval gate、post-release verifier / rollback gate、final release candidate readback、release authorization hold、release authorization readback gate、release verifier preflight gate、release verifier owner review packet、release decision hold、release decision readback、release decision next handoff、release decision input prep、12-Agent War Room 與 owner response 預檢固定成可驗證證據。P2-141 基線已由 feature commit `ee5bf500` 與 deploy marker `306657fd` 正式驗證,S4.9 owner 欄位補強已由 commit `77515bbe` 與 deploy marker `a1ad68b9` 正式驗證;P2-142 已有 feature commit `5de4b3f3` 與 deploy marker `1a2c9e36`,production smoke 仍待補;P2-143 已本地完成,正式驗證後才可進入 P2-144。目前 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-143 正式部署驗證,再由 `P2-144` 承接 owner response readback;不得開啟 runtime writer、Gateway queue、Telegram send、Bot API 或 production write。 -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-142` 已補互動、學習證據面、live read model gate、Redis dry-run gate、learning writeback approval package、Telegram receipt approval package、owner-approved learning dry-run preview、runtime write gate review、post-write verifier package、runtime verifier evidence review、報表真相、TG 戰情室收斂、日週月報、Agent 工作量、圖表化報告、風險自動化政策、報表 runtime 啟動前閘門、no-write dry-run 證據包、fixture/readback/verifier dry-run 證據包、shadow/no-write execution gate、操作類別權限模型、13 類候選操作 dry-run 證據、任務結果稽核軌跡、matched PlayBook 學習缺口、critic / reviewer result capture、owner-approved result capture dry-run / readback、result capture writer dry-run fixture、writer dry-run readback、owner promotion execution gate、owner-approved execution rehearsal、owner acceptance / maintenance window gate、owner acceptance readback / preflight hold、owner-approved preflight release package、owner-approved release readiness readback、owner release approval gate、post-release verifier / rollback gate、final release candidate readback、release authorization hold、release authorization readback gate、release verifier preflight gate、release verifier owner review packet、release decision hold、release decision readback、next handoff readback、decision input prep 與 12-Agent War Room。下一步是 P2-142 正式驗證後進 P2-143;外部 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-143` 已補互動、學習證據面、live read model gate、Redis dry-run gate、learning writeback approval package、Telegram receipt approval package、owner-approved learning dry-run preview、runtime write gate review、post-write verifier package、runtime verifier evidence review、報表真相、TG 戰情室收斂、日週月報、Agent 工作量、圖表化報告、風險自動化政策、報表 runtime 啟動前閘門、no-write dry-run 證據包、fixture/readback/verifier dry-run 證據包、shadow/no-write execution gate、操作類別權限模型、13 類候選操作 dry-run 證據、任務結果稽核軌跡、matched PlayBook 學習缺口、critic / reviewer result capture、owner-approved result capture dry-run / readback、result capture writer dry-run fixture、writer dry-run readback、owner promotion execution gate、owner-approved execution rehearsal、owner acceptance / maintenance window gate、owner acceptance readback / preflight hold、owner-approved preflight release package、owner-approved release readiness readback、owner release approval gate、post-release verifier / rollback gate、final release candidate readback、release authorization hold、release authorization readback gate、release verifier preflight gate、release verifier owner review packet、release decision hold、release decision readback、next handoff readback、decision input prep、12-Agent War Room 與 owner response 預檢。下一步是 P2-143 正式驗證後進 P2-144 owner response readback;外部 registry / package source / host probe / SSH / kubectl / 工具安裝 / CI 變更 / 實際 PR creation / Telegram 實發與 learning write 仍需 gate。 完成度計算模型: @@ -1157,7 +1167,8 @@ UI: | P2-139 | 完成 | 100 | OpenClaw + Hermes + NemoTron | release decision readback | `ai_agent_result_capture_release_decision_readback_v1` / schema / snapshot / 只讀 API / governance UI;feature commit `d41b1a38`、deploy marker `df867bd6` 已正式驗證;承接 P2-138,只讀回 5 個 release decision readback、5 個 owner decision readback、5 個 verifier decision readback、5 個 rollback decision readback、5 個 maintenance window decision readback、5 個 live-apply decision readback、6 個 blocked readback transition、5 個 operator action;需批准 `12`、阻擋 `12`;runtime authority 固定 `result_capture_release_decision_readback_only_no_live_write`;owner release authorized / owner review approved / owner decision approved / verifier decision approved / maintenance window approved / release decision passed / release authorization granted / passed / rollback release / live apply release / writer apply / execution apply / receipt write / reviewer queue / Gateway / Telegram / Bot API / result capture / learning / PlayBook trust / production write / secret read / destructive operation 全為 `0` | 本地 P2-139 API/service pytest `7 passed`、JSON parse、Python compile、i18n key mirror `11809` 通過;production API readback、desktop / mobile smoke、水平溢位 `0`、P2-139 卡片危險控制 `0`、console error `0`、HTTP 4xx/5xx `0`;不得把 P2-139 當 runtime gate,已可由 P2-140 承接 | | P2-140 | 完成 | 100 | OpenClaw + Hermes + NemoTron | release decision next handoff readback | `ai_agent_result_capture_release_decision_next_handoff_v1` / schema / snapshot / 只讀 API / governance UI;feature commit `2fe31c91`、deploy marker `40741425` 已正式驗證,後續 deploy markers `0ae1a25d` 與 `a6b2d187` 已重驗;承接 P2-139,只讀回下一關交接並隔離 P2-139 自我迴圈;固定 5 個 next-gate handoff、1 個 stale operator action containment、6 個 blocked handoff transition、5 個 operator action;需批准 `12`、阻擋 `12`;runtime authority 固定 `result_capture_release_decision_next_handoff_only_no_live_write`;owner release authorized / owner review approved / owner decision approved / verifier decision approved / maintenance window approved / release decision passed / release authorization granted / passed / rollback release / live apply release / writer apply / execution apply / receipt write / reviewer queue / Gateway / Telegram / Bot API / result capture / learning / PlayBook trust / production write / secret read / destructive operation 全為 `0` | 本地 P2-140 + P2-139 API/service regression `14 passed`、JSON parse、Python compile、i18n key mirror `11837`、guard 與 doc secret sanity 通過;production API readback、desktop / mobile smoke、in-app browser smoke、水平溢位 `0`、內容區危險控制 `0`、console error `0`、HTTP 4xx/5xx `0`;不得把 P2-140 當 runtime gate,已可由 P2-141 承接 | | P2-141 | 完成 | 100 | OpenClaw + Hermes + NemoTron | release decision input prep | `ai_agent_result_capture_release_decision_input_prep_v1` / schema / snapshot / 只讀 API / governance UI;feature commit `ee5bf500`、deploy marker `306657fd` 已完成 P2-141 基線正式驗證;S4.9 補強 commit `77515bbe`、deploy marker `a1ad68b9` 已完成正式驗證;承接 P2-140 next handoff,整理 5 個 decision input packet、18 個 missing input field、6 個 blocked input transition、5 個 operator action;owner release packet 已補齊 S4.9 owner role / team、decision、decision reason、affected scope、redacted evidence refs、followup owner;需批准 `12`、阻擋 `12`;runtime authority 固定 `result_capture_release_decision_input_prep_only_no_live_write`;owner release authorized / owner review approved / owner decision approved / verifier decision approved / maintenance window approved / release decision passed / release authorization granted / passed / rollback release / live apply release / writer apply / execution apply / receipt write / reviewer queue / Gateway / Telegram / Bot API / result capture / learning / PlayBook trust / production write / secret read / destructive operation 全為 `0` | P2-141 基線 production API readback、desktop / mobile smoke、水平溢位 `0`、P2-141 卡片危險控制 `0`、console error `0`、HTTP 4xx/5xx `0`;S4.9 補強 production API readback、owner 六欄位、缺欄位 `18`、desktop / mobile smoke、in-app browser smoke、禁用外露值 `0`、水平溢位 `0`、危險按鈕 `0`、console error `0`、HTTP 4xx/5xx `0`;本地 P2-141 + P2-140 API/service regression `15 passed`、JSON parse、Python compile、i18n key mirror `11864`、Web typecheck、guard 與 doc secret sanity 通過;不得把 input prep 當 runtime gate,已可由 P2-142 承接 | -| P2-142 | 本地完成 | 72 | OpenClaw + Hermes + NemoTron + SRE + Security + DevOps + Data/DR + Supply Chain + Product/UI + QA + Market + Telegram | 12-Agent War Room 編組 | `ai_agent_12_agent_war_room_v1` / schema / snapshot / 只讀 API / governance UI;12 個邏輯工位、12 份 read-only review、總工作量 `82`、evidence `84`、需批准 `61`、阻擋項 `54`、市場 refresh candidate `5`、日週月報 cadence `3`;runtime authority 固定 `12_agent_war_room_read_only_no_live_write`;live write / Telegram send / Bot API / production write / paid API / SDK install / secret read / destructive operation 全為 `0` | 本地 P2-142 API/service pytest `7 passed`、JSON parse、Python compile、i18n key mirror `11894`、Web typecheck、Web production build、guard、doc secret sanity、公開 payload 目標掃描通過;正式部署與 production desktop / mobile smoke 待 Gitea CD 完成後補驗,不得把 War Room 可見當 runtime gate,正式驗證後才可由 P2-143 承接 | +| P2-142 | 本地完成 | 72 | OpenClaw + Hermes + NemoTron + SRE + Security + DevOps + Data/DR + Supply Chain + Product/UI + QA + Market + Telegram | 12-Agent War Room 編組 | `ai_agent_12_agent_war_room_v1` / schema / snapshot / 只讀 API / governance UI;feature commit `5de4b3f3`、deploy marker `1a2c9e36`;12 個邏輯工位、12 份 read-only review、總工作量 `82`、evidence `84`、需批准 `61`、阻擋項 `54`、市場 refresh candidate `5`、日週月報 cadence `3`;runtime authority 固定 `12_agent_war_room_read_only_no_live_write`;live write / Telegram send / Bot API / production write / paid API / SDK install / secret read / destructive operation 全為 `0` | 本地 P2-142 API/service pytest `7 passed`、JSON parse、Python compile、i18n key mirror `11894`、Web typecheck、Web production build、guard、doc secret sanity、公開 payload 目標掃描通過;P2-143 已本地承接此基線,但 P2-142 production desktop / mobile smoke 仍需補驗,不得把 War Room 可見當 runtime gate | +| P2-143 | 本地完成 | 100 | OpenClaw + Hermes + NemoTron | owner response 預檢與拒收邊界 | `ai_agent_result_capture_release_decision_owner_response_preflight_v1` / snapshot / 只讀 API / governance UI;承接 P2-141 input prep 與 P2-142 War Room,固定 5 個 response intake lane、18 個 required owner field、6 個 intake validation check、6 個 rejection guard、5 個 operator action、5 個 waiting external response;runtime authority 固定 `result_capture_release_decision_owner_response_preflight_only_no_live_write` | 本地 P2-142 War Room + P2-139 / P2-140 / P2-141 / P2-143 regression `37 passed`、JSON parse、Python compile、Web typecheck、source-control owner response guard、security mirror progress guard、doc secret sanity、禁用值掃描 `0`、diff check 通過;owner response received / accepted / redacted payload / reviewer queue / Gateway / Telegram / Bot API / result capture / learning / PlayBook trust / production write / secret read / destructive operation 全為 `0`;production API / desktop / mobile smoke 待推送後補驗,下一關為 P2-144 owner response readback | ### P3 - 候選 Agent 擴展 diff --git a/docs/evaluations/ai_agent_result_capture_release_decision_owner_response_preflight_2026-06-14.json b/docs/evaluations/ai_agent_result_capture_release_decision_owner_response_preflight_2026-06-14.json new file mode 100644 index 00000000..6294cf1e --- /dev/null +++ b/docs/evaluations/ai_agent_result_capture_release_decision_owner_response_preflight_2026-06-14.json @@ -0,0 +1,394 @@ +{ + "schema_version": "ai_agent_result_capture_release_decision_owner_response_preflight_v1", + "generated_at": "2026-06-14T14:10:00+08:00", + "program_status": { + "overall_completion_percent": 100, + "current_priority": "P2", + "current_task_id": "P2-143", + "next_task_id": "P2-144", + "read_only_mode": true, + "runtime_authority": "result_capture_release_decision_owner_response_preflight_only_no_live_write", + "status_note": "P2-143 在 P2-142 War Room 基線後,只把 P2-141 決策輸入準備包轉成 owner response 預檢與拒收邊界;不得把預檢視為正式收件、批准、驗證通過、維護窗口核准、Gateway 寫入、Telegram 送出或 production target 寫入。" + }, + "source_refs": [ + "docs/evaluations/ai_agent_12_agent_war_room_2026-06-14.json", + "docs/evaluations/ai_agent_result_capture_release_decision_input_prep_2026-06-14.json", + "docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md#62-建立-release-decision-input-prep", + "docs/HARD_RULES.md#iwooos-security-governance" + ], + "prior_decision_input_prep": { + "schema_version": "ai_agent_result_capture_release_decision_input_prep_v1", + "current_task_id": "P2-141", + "next_task_id": "P2-142", + "decision_input_packet_count": 5, + "missing_input_field_count": 18, + "blocked_input_transition_count": 6, + "operator_action_count": 5, + "approval_required_subtotal": 12, + "blocked_and_critical_subtotal": 12, + "readiness_note": "P2-141 已固定 owner release、verifier、rollback owner、maintenance window、live apply 五類決策輸入與 18 個缺欄位;P2-143 只能做預檢與拒收邊界,不得接收未遮罩 payload 或釋放 writer。", + "owner_release_authorized_count": 0, + "owner_release_approved_count": 0, + "owner_review_approved_count": 0, + "owner_decision_approved_count": 0, + "verifier_decision_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "final_release_candidate_approved_count": 0, + "final_release_candidate_pass_count": 0, + "release_decision_pass_count": 0, + "release_authorization_granted_count": 0, + "release_authorization_pass_count": 0, + "rollback_release_pass_count": 0, + "live_apply_release_pass_count": 0, + "writer_apply_count": 0, + "execution_apply_count": 0, + "receipt_write_count": 0, + "reviewer_queue_write_count": 0, + "gateway_queue_write_count": 0, + "telegram_send_count": 0, + "bot_api_call_count": 0, + "report_receipt_write_count": 0, + "result_capture_write_count": 0, + "learning_write_count": 0, + "playbook_trust_write_count": 0, + "production_write_count": 0, + "secret_read_count": 0, + "destructive_operation_count": 0 + }, + "owner_response_preflight_truth": { + "p2_141_input_prep_loaded": true, + "p2_142_war_room_baseline_preserved": true, + "required_owner_fields_declared": true, + "required_verifier_fields_declared": true, + "required_rollback_fields_declared": true, + "required_maintenance_window_fields_declared": true, + "required_live_apply_fields_declared": true, + "redaction_contract_loaded": true, + "preflight_only_mode": true, + "no_raw_payload_required": true, + "rejection_policy_active": true, + "truth_note": "P2-143 只建立 owner response 進入前的預檢與拒收條件;P2-142 War Room 基線維持不變,沒有收到、接受、拒絕或保存任何正式回覆,也沒有啟動 reviewer、Gateway、Telegram、Bot API、learning 或 production 寫入。", + "owner_response_received": false, + "owner_response_accepted": false, + "owner_response_rejected": false, + "redacted_payload_ingested": false, + "owner_release_authorized": false, + "owner_release_approved": false, + "owner_review_approved": false, + "owner_decision_approved": false, + "verifier_decision_approved": false, + "maintenance_window_approved": false, + "rollback_owner_confirmed": false, + "post_release_verifier_ready": false, + "final_release_candidate_approved": false, + "final_release_candidate_passed": false, + "release_decision_passed": false, + "release_authorization_granted": false, + "release_authorization_passed": false, + "rollback_release_passed": false, + "live_apply_release_passed": false, + "writer_apply_enabled": false, + "execution_apply_enabled": false, + "receipt_write_enabled": false, + "reviewer_queue_write_enabled": false, + "gateway_queue_write_enabled": false, + "telegram_send_enabled": false, + "bot_api_call_enabled": false, + "report_receipt_write_enabled": false, + "result_capture_write_enabled": false, + "learning_write_enabled": false, + "playbook_trust_write_enabled": false, + "production_write_enabled": false, + "secret_read_enabled": false, + "destructive_operation_enabled": false, + "owner_response_received_count": 0, + "owner_response_accepted_count": 0, + "owner_response_rejected_count": 0, + "redacted_payload_ingested_count": 0, + "owner_release_authorized_count": 0, + "owner_release_approved_count": 0, + "owner_review_approved_count": 0, + "owner_decision_approved_count": 0, + "verifier_decision_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "final_release_candidate_approved_count": 0, + "final_release_candidate_pass_count": 0, + "release_decision_pass_count": 0, + "release_authorization_granted_count": 0, + "release_authorization_pass_count": 0, + "rollback_release_pass_count": 0, + "live_apply_release_pass_count": 0, + "writer_apply_count": 0, + "execution_apply_count": 0, + "receipt_write_count": 0, + "reviewer_queue_write_count": 0, + "gateway_queue_write_count": 0, + "telegram_send_count": 0, + "bot_api_call_count": 0, + "report_receipt_write_count": 0, + "result_capture_write_count": 0, + "learning_write_count": 0, + "playbook_trust_write_count": 0, + "production_write_count": 0, + "secret_read_count": 0, + "destructive_operation_count": 0 + }, + "response_intake_lanes": [ + { + "lane_id": "owner_release_response_preflight", + "display_name": "Owner release 回覆預檢", + "source_packet_id": "decision_input_owner_release", + "owner_agent": "openclaw", + "current_task_id": "P2-143", + "target_next_task_id": "P2-144", + "intake_status": "waiting_for_external_owner_response", + "required_fields": [ + "owner_role_team", + "owner_decision", + "decision_reason", + "affected_scope", + "redacted_evidence_refs", + "followup_owner" + ], + "preflight_summary": "僅允許 owner 角色 / 團隊、明確決策、理由、影響範圍、遮罩 evidence refs 與 follow-up owner 進入下一步;缺任一欄位即維持 blocked。", + "accepted": false, + "redacted_payload_ingested": false, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:8b8f35b415489320f977a2e02aa56adaf11a9571a3e4cfe88aa6f257215970c3" + }, + { + "lane_id": "verifier_response_preflight", + "display_name": "Verifier 回覆預檢", + "source_packet_id": "decision_input_verifier", + "owner_agent": "openclaw", + "current_task_id": "P2-143", + "target_next_task_id": "P2-144", + "intake_status": "waiting_for_external_owner_response", + "required_fields": ["verifier_scope", "verification_criteria", "failure_escalation"], + "preflight_summary": "只檢查 verifier scope、驗證準則與失敗升級條件是否齊備;不得啟動 verifier runtime。", + "accepted": false, + "redacted_payload_ingested": false, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:cb9f1e92f141d49fc8dbb66db1730a0bd596a9f5c7d4811d8525066410b3a269" + }, + { + "lane_id": "rollback_owner_response_preflight", + "display_name": "Rollback owner 回覆預檢", + "source_packet_id": "decision_input_rollback_owner", + "owner_agent": "hermes", + "current_task_id": "P2-143", + "target_next_task_id": "P2-144", + "intake_status": "waiting_for_external_owner_response", + "required_fields": ["rollback_owner", "rollback_condition", "rollback_validation_plan"], + "preflight_summary": "只檢查 rollback owner、回滾條件與驗證計畫是否齊備;不得確認 rollback owner 或執行回滾。", + "accepted": false, + "redacted_payload_ingested": false, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:fdf91190ca41e61e3ca94f36f21d71e7f66aa5820927c0279eb61a51100bcbdd" + }, + { + "lane_id": "maintenance_window_response_preflight", + "display_name": "維護窗口回覆預檢", + "source_packet_id": "decision_input_maintenance_window", + "owner_agent": "openclaw", + "current_task_id": "P2-143", + "target_next_task_id": "P2-144", + "intake_status": "waiting_for_external_owner_response", + "required_fields": ["maintenance_window", "impact_scope", "notification_plan"], + "preflight_summary": "只檢查維護時間、影響範圍與通知計畫是否齊備;不得批准維護窗口或送出通知。", + "accepted": false, + "redacted_payload_ingested": false, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:293c2e57ac83fd6404ddc2cb6756307370096296ac9eb421772017456df9aa92" + }, + { + "lane_id": "live_apply_response_preflight", + "display_name": "正式套用回覆預檢", + "source_packet_id": "decision_input_live_apply", + "owner_agent": "openclaw", + "current_task_id": "P2-143", + "target_next_task_id": "P2-144", + "intake_status": "waiting_for_external_owner_response", + "required_fields": ["live_apply_strategy", "stop_condition", "acceptance_evidence"], + "preflight_summary": "只檢查正式套用策略、停止條件與驗收證據是否齊備;不得釋放 writer 或 execution apply。", + "accepted": false, + "redacted_payload_ingested": false, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:5e24d2fa48f38c73e3cbf25e7752df1666f1cd8cd6eb225432dd4ae9933f9332" + } + ], + "intake_validation_checks": [ + { + "check_id": "owner_identity_and_decision_fields_required", + "status": "waiting_for_owner_response", + "requirement": "owner role / team、decision、decision reason、affected scope、redacted evidence refs、followup owner 必須同時存在。", + "runtime_write_allowed": false + }, + { + "check_id": "redacted_evidence_refs_only", + "status": "not_satisfied", + "requirement": "只接受遮罩 evidence refs,不接受敏感值、token、private key、cookie、驗證標頭或未遮罩 runtime 資料。", + "runtime_write_allowed": false + }, + { + "check_id": "verifier_and_failure_escalation_required", + "status": "not_satisfied", + "requirement": "verifier scope、verification criteria 與 failure escalation 必須齊備,才能進入下一個只讀 readback。", + "runtime_write_allowed": false + }, + { + "check_id": "rollback_owner_and_maintenance_window_required", + "status": "not_satisfied", + "requirement": "rollback owner、rollback condition、maintenance window、impact scope 與 notification plan 必須齊備;本關卡不批准維護窗口。", + "runtime_write_allowed": false + }, + { + "check_id": "live_apply_requires_stop_and_acceptance", + "status": "not_satisfied", + "requirement": "live apply strategy、stop condition 與 acceptance evidence 必須齊備;本關卡不釋放 writer。", + "runtime_write_allowed": false + }, + { + "check_id": "awooop_approval_not_security_approval", + "status": "blocked_by_policy", + "requirement": "AwoooP approval、UI 可見、CD success 或 smoke pass 不得被視為 IwoooS 資安批准或 runtime 授權。", + "runtime_write_allowed": false + } + ], + "rejection_guards": [ + { + "guard_id": "reject_raw_secret_material", + "status": "active", + "reason": "含敏感值、token、private key、cookie、驗證標頭、runner token、webhook secret 或未遮罩 runtime 資料時必須拒收。", + "runtime_write_allowed": false + }, + { + "guard_id": "reject_missing_owner_identity", + "status": "active", + "reason": "缺 owner role / team 或 follow-up owner 時必須拒收,不得以口頭批准補位。", + "runtime_write_allowed": false + }, + { + "guard_id": "reject_missing_decision_reason_scope", + "status": "active", + "reason": "缺 decision、decision reason 或 affected scope 時必須拒收。", + "runtime_write_allowed": false + }, + { + "guard_id": "reject_unredacted_evidence_refs", + "status": "active", + "reason": "缺遮罩 evidence refs 或 evidence refs 可回推出敏感值時必須拒收。", + "runtime_write_allowed": false + }, + { + "guard_id": "reject_execution_request", + "status": "active", + "reason": "owner response 若要求直接執行、寫入、發送、reload、restart、active scan 或 production apply,本關卡必須拒收並維持 runtime gate 0。", + "runtime_write_allowed": false + }, + { + "guard_id": "reject_approval_source_confusion", + "status": "active", + "reason": "AwoooP approval、治理頁卡片、候選可見或部署成功不得替代 IwoooS 資安批准。", + "runtime_write_allowed": false + } + ], + "operator_actions": [ + { + "action_id": "prepare_owner_response_preflight_checklist", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "準備 owner response 預檢 checklist;不得記錄 secret、不得把預檢當成正式收件。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_redacted_evidence_ref_review", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "準備遮罩 evidence refs 審查欄位;只允許 refs 與證據摘要,不保存敏感值。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_verifier_acceptance_boundary", + "owner_agent": "openclaw", + "status": "approval_required", + "operator_instruction": "整理 verifier scope、criteria 與 failure escalation 邊界;不得啟動 verifier runtime。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_rollback_maintenance_crosscheck", + "owner_agent": "hermes", + "status": "approval_required", + "operator_instruction": "整理 rollback owner、maintenance window 與 notification plan 的交叉檢查;不得批准維護窗口。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_p2_144_owner_response_readback", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "下一關只能建立 owner response readback;不得寫 reviewer queue、Gateway queue、Telegram、Bot API、learning 或 production target。", + "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": "前端只能顯示預檢摘要、必填欄位、拒收規則、只讀狀態與遮罩 evidence hash;不得顯示非公開溝通、未脫敏指令、推理草稿、敏感值、驗證標頭或未遮罩 runtime 資料。" + }, + "rollups": { + "response_intake_lane_count": 5, + "required_owner_field_count": 18, + "intake_validation_check_count": 6, + "rejection_guard_count": 6, + "operator_action_count": 5, + "waiting_external_response_count": 5, + "approval_required_subtotal": 12, + "blocked_and_critical_subtotal": 12, + "owner_response_received_count": 0, + "owner_response_accepted_count": 0, + "owner_response_rejected_count": 0, + "redacted_payload_ingested_count": 0, + "owner_release_authorized_count": 0, + "owner_release_approved_count": 0, + "owner_review_approved_count": 0, + "owner_decision_approved_count": 0, + "verifier_decision_approved_count": 0, + "maintenance_window_approved_count": 0, + "rollback_owner_confirmed_count": 0, + "post_release_verifier_ready_count": 0, + "final_release_candidate_approved_count": 0, + "final_release_candidate_pass_count": 0, + "release_decision_pass_count": 0, + "release_authorization_granted_count": 0, + "release_authorization_pass_count": 0, + "rollback_release_pass_count": 0, + "live_apply_release_pass_count": 0, + "writer_apply_count": 0, + "execution_apply_count": 0, + "receipt_write_count": 0, + "reviewer_queue_write_count": 0, + "gateway_queue_write_count": 0, + "telegram_send_count": 0, + "bot_api_call_count": 0, + "report_receipt_write_count": 0, + "result_capture_write_count": 0, + "learning_write_count": 0, + "playbook_trust_write_count": 0, + "production_write_count": 0, + "secret_read_count": 0, + "destructive_operation_count": 0 + } +} diff --git a/docs/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 3fb4a33b..dd3ce53f 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 @@ -679,6 +679,8 @@ Alert / Sentry / SigNoz / Gitea / Market Watch / Operator | `docs/evaluations/ai_agent_result_capture_release_decision_readback_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-decision-readback` | P2-139 release decision readback;承接 P2-138 release decision hold,建立 5 個 release decision readback、5 個 owner decision readback、5 個 verifier decision readback、5 個 rollback decision readback、5 個 maintenance window decision readback、5 個 live-apply decision readback、6 個 blocked readback transition 與 5 個 operator action;runtime authority 固定 `result_capture_release_decision_readback_only_no_live_write`;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、canonical runtime target read、live query、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部 `0 / false`;feature commit `d41b1a38`、deploy marker `df867bd6`、正式 API readback、desktop / mobile smoke、禁用內部協作片語 `0`、水平溢位 `0`、危險控制 `0`、console error `0`、HTTP 4xx/5xx `0` 已完成,下一步 P2-140 | | `docs/evaluations/ai_agent_result_capture_release_decision_next_handoff_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-decision-next-handoff` | P2-140 release decision next handoff readback;承接 P2-139 release decision readback,建立 5 個 next-gate handoff、1 個 stale operator action containment、6 個 blocked handoff transition 與 5 個 operator action;runtime authority 固定 `result_capture_release_decision_next_handoff_only_no_live_write`;P2-139 的 `prepare_p2_139_release_decision_readback` 自我迴圈已標示為 `contained_read_only`,真正下一步為 P2-141;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、canonical runtime target read、live query、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部 `0 / false`;feature commit `2fe31c91`、deploy marker `40741425`、最新 recheck deploy marker `a6b2d187`、正式 API readback、desktop / mobile smoke、in-app browser smoke、禁用內部協作片語 `0`、水平溢位 `0`、內容區危險控制 `0`、console error `0`、HTTP 4xx/5xx `0` 已完成,下一步 P2-141 | | `docs/evaluations/ai_agent_result_capture_release_decision_input_prep_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-decision-input-prep` | P2-141 release decision input prep;承接 P2-140 release decision next handoff,把下一關交接整理成 5 個 decision input packet、18 個 missing input field、6 個 blocked input transition 與 5 個 operator action;owner release packet 已補齊 S4.9 owner role / team、decision、decision reason、affected scope、redacted evidence refs、followup owner;runtime authority 固定 `result_capture_release_decision_input_prep_only_no_live_write`;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、canonical runtime target read、live query、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部 `0 / false`;feature commit `ee5bf500`、deploy marker `306657fd`、Gitea code-review `2954` / CD `2953` success 已完成 15 欄位基線正式驗證;S4.9 補強 commit `77515bbe`、deploy marker `a1ad68b9`、Gitea code-review `2956` / CD `2955` success,正式 API readback missing input field `18`、owner 六欄位、desktop / mobile smoke、in-app browser smoke、禁用外露值 `0`、水平溢位 `0`、危險按鈕 `0`、console error `0`、HTTP 4xx/5xx `0` 已完成,已可由 P2-142 承接 | +| `docs/evaluations/ai_agent_12_agent_war_room_2026-06-14.json` + `GET /api/v1/agents/agent-12-agent-war-room` | P2-142 12-Agent War Room readback;建立 12 個邏輯工位、12 份 read-only review、總工作量 `82`、evidence `84`、需批准 `61`、阻擋項 `54`、市場 refresh candidate `5`、日週月報 cadence `3`;runtime authority 固定 `12_agent_war_room_read_only_no_live_write`;live write、Telegram send、Bot API、production write、paid API、SDK install、secret read 與 destructive operation 全部 `0 / false`;feature commit `5de4b3f3` 與 deploy marker `1a2c9e36` 已進 `gitea/main`,本地 API/service pytest、JSON parse、Python compile、Web typecheck、Web production build、guard、doc secret sanity 與公開 payload 目標掃描通過;production desktop / mobile smoke 待補驗,已由 P2-143 本地承接 | +| `docs/evaluations/ai_agent_result_capture_release_decision_owner_response_preflight_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-decision-owner-response-preflight` | P2-143 owner response preflight;承接 P2-141 decision input prep 與 P2-142 War Room 基線,建立 5 條 response intake lane、18 個 required owner field、6 個 intake validation check、6 個 rejection guard、5 個 operator action 與 5 個 waiting external response;runtime authority 固定 `result_capture_release_decision_owner_response_preflight_only_no_live_write`;owner response received / accepted / rejected、redacted payload ingested、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部 `0 / false`;本地整合 `5de4b3f3` 後 API/service regression `37 passed`、JSON parse、Python compile、Web typecheck、source-control owner response guard、security mirror progress guard、doc secret sanity、禁用外露值掃描與 `git diff --check` 通過;正式部署與 production desktop / mobile smoke 待 CD marker 後補驗,下一步 P2-144 owner response readback | | `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 主動營運委派與版本生命週期契約 @@ -809,6 +811,8 @@ Repo / registry / release notes / K8s / host / observability / backup evidence 60. 建立 release decision readback。✅ P2-139 已完成並正式驗證;release decision readback `5`、owner decision readback `5`、verifier decision readback `5`、rollback decision readback `5`、maintenance window decision readback `5`、live-apply decision readback `5`、blocked readback transition `6`、operator action `5`,approval-required release / owner / verifier / rollback / maintenance / live apply `2 / 2 / 2 / 2 / 2 / 2`、blocked release / owner / verifier / rollback / maintenance / live apply `1 / 1 / 1 / 1 / 1 / 1`、critical blocker `6`;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 仍為 `0 / false`;本地 API/service pytest `7 passed`、JSON parse、Python compile、i18n key mirror 通過;deploy marker `df867bd6`、正式 API readback 與 desktop / mobile smoke 已完成。已可由 P2-140 承接。 61. 建立 release decision next handoff readback。✅ P2-140 已完成並正式驗證;next-gate handoff `5`、stale operator action containment `1`、blocked handoff transition `6`、operator action `5`、approval required subtotal `12`、blocked + critical subtotal `12`;P2-139 的 `prepare_p2_139_release_decision_readback` 自我迴圈已標示為 `contained_read_only`,真正下一步固定為 P2-141;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 仍為 `0 / false`;P2-140 + P2-139 regression `14 passed`、JSON parse、Python compile、i18n key mirror、guard 與 doc secret sanity 通過;deploy marker `40741425`、最新 recheck deploy marker `a6b2d187`、正式 API readback、in-app browser、desktop / mobile smoke 已完成。已可由 P2-141 承接。 62. 建立 release decision input prep。✅ P2-141 基線與 S4.9 owner 欄位補強皆已完成並正式驗證;decision input packet `5`、missing input field `18`、blocked input transition `6`、operator action `5`、approval required subtotal `12`、blocked + critical subtotal `12`;owner release packet 已補齊 S4.9 owner role / team、decision、decision reason、affected scope、redacted evidence refs、followup owner;P2-141 只把 P2-140 next handoff 轉成 owner release、verifier、rollback owner、maintenance window、live apply 五類決策輸入準備包,尚未寫入 reviewer queue、Gateway queue、Telegram、Bot API、result capture、learning、PlayBook trust 或 production target;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 仍為 `0 / false`;P2-141 + P2-140 regression `15 passed`、JSON parse、Python compile、i18n key mirror、Web typecheck、guard 與 doc secret sanity 通過;基線 deploy marker `306657fd`、S4.9 補強 deploy marker `a1ad68b9`、正式 API readback、desktop / mobile smoke 與 in-app browser smoke 已完成。已可由 P2-142 承接。 +63. 建立 12-Agent War Room readback。✅ P2-142 已本地完成;12 個邏輯工位、12 份 read-only review、總工作量 `82`、evidence `84`、需批准 `61`、阻擋項 `54`、市場 refresh candidate `5`、日週月報 cadence `3`;runtime writer、Telegram send、Bot API、production write、paid API、SDK install、secret read、destructive operation 仍為 `0 / false`;feature commit `5de4b3f3` 與 deploy marker `1a2c9e36` 已進 `gitea/main`,本地 API/service pytest、JSON parse、Python compile、Web typecheck、Web production build、guard、doc secret sanity 與公開 payload 掃描通過;production smoke 待補驗。已由 P2-143 本地承接。 +64. 建立 owner response preflight 與拒收邊界。✅ P2-143 已本地完成;承接 P2-141 decision input prep 與 P2-142 War Room 基線,固定 response intake lane `5`、required owner field `18`、intake validation check `6`、rejection guard `6`、operator action `5`、waiting external response `5`;owner response received / accepted / rejected、redacted payload ingested、reviewer queue write、Gateway queue write、Telegram send、Bot API、result capture、learning、PlayBook trust、production write、secret read、destructive operation 仍為 `0 / false`;本地 P2-142 War Room + P2-139 至 P2-143 regression `37 passed`、JSON parse、Python compile、Web typecheck、guard、doc secret sanity、禁用外露值掃描與 `git diff --check` 通過;正式部署與 production smoke 待 CD marker 後補驗。下一步 P2-144 owner response readback。 #### 3.2.1d 2026-06-11 Agent 互動、學習與成長證據面