From 8795f10025e81ba780394c6c05ec8439999e42c8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 14 Jun 2026 15:16:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(governance):=20=E6=96=B0=E5=A2=9E=20P2-144?= =?UTF-8?q?=20owner=20response=20=E5=9B=9E=E8=AE=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api/src/api/v1/agents.py | 33 ++ ...elease_decision_owner_response_readback.py | 379 ++++++++++++++++ ...elease_decision_owner_response_readback.py | 115 +++++ ...se_decision_owner_response_readback_api.py | 53 +++ apps/web/messages/en.json | 39 ++ apps/web/messages/zh-TW.json | 39 ++ .../tabs/automation-inventory-tab.tsx | 160 ++++++- apps/web/src/lib/api-client.ts | 131 +++++- docs/LOGBOOK.md | 31 ++ ...AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md | 16 +- ...on_owner_response_readback_2026-06-14.json | 408 ++++++++++++++++++ ...-04-15-MASTER-ai-autonomous-flywheel-v2.md | 2 + 12 files changed, 1400 insertions(+), 6 deletions(-) create mode 100644 apps/api/src/services/ai_agent_result_capture_release_decision_owner_response_readback.py create mode 100644 apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_readback.py create mode 100644 apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_readback_api.py create mode 100644 docs/evaluations/ai_agent_result_capture_release_decision_owner_response_readback_2026-06-14.json diff --git a/apps/api/src/api/v1/agents.py b/apps/api/src/api/v1/agents.py index 6ede35b32..3b47bf5ee 100644 --- a/apps/api/src/api/v1/agents.py +++ b/apps/api/src/api/v1/agents.py @@ -139,6 +139,9 @@ from src.services.ai_agent_result_capture_release_decision_input_prep import ( 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_release_decision_owner_response_readback import ( + load_latest_ai_agent_result_capture_release_decision_owner_response_readback, +) from src.services.ai_agent_result_capture_owner_promotion_review import ( load_latest_ai_agent_result_capture_owner_promotion_review, ) @@ -2457,6 +2460,36 @@ async def get_agent_result_capture_release_decision_owner_response_preflight() - ) from exc +@router.get( + "/agent-result-capture-release-decision-owner-response-readback", + response_model=dict[str, Any], + summary="取得 AI Agent result capture release decision owner response readback", + description=( + "讀取最新已提交的 P2-144 release decision owner response readback;" + "此端點只讀回 P2-143 預檢後的外部 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_readback() -> dict[str, Any]: + """Return the latest read-only release decision owner-response readback.""" + try: + payload = await asyncio.to_thread(load_latest_ai_agent_result_capture_release_decision_owner_response_readback) + 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_readback_invalid", error=str(exc)) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="AI Agent result capture release decision owner response readback 無效", + ) 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_readback.py b/apps/api/src/services/ai_agent_result_capture_release_decision_owner_response_readback.py new file mode 100644 index 000000000..adc8de8a7 --- /dev/null +++ b/apps/api/src/services/ai_agent_result_capture_release_decision_owner_response_readback.py @@ -0,0 +1,379 @@ +""" +AI Agent result capture release decision owner-response readback snapshot. + +Loads the latest committed P2-144 owner-response readback package. This module +only reads back the P2-143 preflight state; it never treats absence/readback 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_readback_*.json" +_SCHEMA_VERSION = "ai_agent_result_capture_release_decision_owner_response_readback_v1" +_RUNTIME_AUTHORITY = "result_capture_release_decision_owner_response_readback_only_no_live_write" + + +def load_latest_ai_agent_result_capture_release_decision_owner_response_readback( + evaluations_dir: Path | None = None, +) -> dict[str, Any]: + """Load the newest committed release decision owner-response readback.""" + 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 readback 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_readback_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-144", + "next_task_id": "P2-145", + "read_only_mode": True, + "runtime_authority": _RUNTIME_AUTHORITY, + "overall_completion_percent": 100, + } + mismatches = _mismatches(status, expected) + if mismatches: + raise ValueError(f"{label}: program_status mismatch: {mismatches}") + if not status.get("status_note"): + raise ValueError(f"{label}: program_status.status_note is required") + + +def _require_prior(payload: dict[str, Any], label: str) -> None: + prior = payload.get("prior_owner_response_preflight") or {} + expected = { + "schema_version": "ai_agent_result_capture_release_decision_owner_response_preflight_v1", + "current_task_id": "P2-143", + "next_task_id": "P2-144", + "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, + } + expected.update(_owner_response_zero_counts()) + mismatches = _mismatches(prior, expected) + if mismatches: + raise ValueError(f"{label}: prior_owner_response_preflight mismatch: {mismatches}") + if not prior.get("readiness_note"): + raise ValueError(f"{label}: prior_owner_response_preflight.readiness_note is required") + + +def _require_truth(payload: dict[str, Any], label: str) -> None: + truth = payload.get("owner_response_readback_truth") or {} + required_true = { + "p2_143_preflight_loaded", + "p2_142_war_room_baseline_preserved", + "owner_response_readback_ready", + "readback_only_mode", + "no_external_response_received", + "no_raw_payload_required", + "redaction_contract_loaded", + "rejection_policy_preserved", + } + missing = sorted(field for field in required_true if truth.get(field) is not True) + if missing: + raise ValueError(f"{label}: owner response readback 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_readback_truth.truth_note is required") + + +def _require_response_readback_lanes(payload: dict[str, Any], label: str) -> None: + items = payload.get("response_readback_lanes") or [] + _require_ids( + items, + "readback_id", + { + "owner_release_response_readback", + "verifier_response_readback", + "rollback_owner_response_readback", + "maintenance_window_response_readback", + "live_apply_response_readback", + }, + label, + "response readback lanes", + ) + for item in items: + item_id = item.get("readback_id") + expected = { + "current_task_id": "P2-144", + "target_next_task_id": "P2-145", + "readback_status": "no_external_response_received", + "response_received": False, + "response_accepted": False, + "response_rejected": False, + "redacted_payload_ingested": False, + "runtime_write_allowed": False, + "telegram_send_allowed": False, + } + mismatches = _mismatches(item, expected) + if mismatches: + raise ValueError(f"{label}: response readback 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 readback lane {item_id}.required_fields is required") + if not item.get("source_lane_id"): + raise ValueError(f"{label}: response readback lane {item_id}.source_lane_id is required") + if not item.get("readback_summary"): + raise ValueError(f"{label}: response readback lane {item_id}.readback_summary is required") + if not _is_redacted_sha256(item.get("evidence_hash")): + raise ValueError(f"{label}: response readback lane {item_id}.evidence_hash must be redacted sha256") + + +def _require_validation_checks(payload: dict[str, Any], label: str) -> None: + items = payload.get("readback_validation_checks") or [] + _require_count(items, 6, label, "readback 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}: readback validation check {item_id} status is invalid") + if item.get("runtime_write_allowed") is not False: + raise ValueError(f"{label}: readback validation check {item_id} must keep runtime_write_allowed=false") + if not item.get("requirement"): + raise ValueError(f"{label}: readback validation check {item_id}.requirement is required") + + +def _require_rejection_guards(payload: dict[str, Any], label: str) -> None: + items = payload.get("readback_rejection_guards") or [] + _require_count(items, 6, label, "readback rejection guards") + for item in items: + item_id = item.get("guard_id") + if item.get("status") != "active": + raise ValueError(f"{label}: readback rejection guard {item_id} status must remain active") + if item.get("runtime_write_allowed") is not False: + raise ValueError(f"{label}: readback rejection guard {item_id} must keep runtime_write_allowed=false") + if not item.get("reason"): + raise ValueError(f"{label}: readback 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")) + stale_ids = {"p2_139", "p2_140", "p2_141", "p2_142"} + if any(stale_id in item_id for stale_id in stale_ids): + raise ValueError(f"{label}: operator action {item_id} must not point back to stale release gates") + 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_readback_lanes") or []) + expected = { + "response_readback_lane_count": len(payload.get("response_readback_lanes") or []), + "required_owner_field_count": required_owner_field_count, + "readback_validation_check_count": len(payload.get("readback_validation_checks") or []), + "readback_rejection_guard_count": len(payload.get("readback_rejection_guards") or []), + "operator_action_count": len(payload.get("operator_actions") or []), + "waiting_external_response_count": len(payload.get("response_readback_lanes") or []), + "no_external_response_received_count": len(payload.get("response_readback_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_readback.py b/apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_readback.py new file mode 100644 index 000000000..f572fb673 --- /dev/null +++ b/apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_readback.py @@ -0,0 +1,115 @@ +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_readback import ( + load_latest_ai_agent_result_capture_release_decision_owner_response_readback, +) + + +def test_load_latest_release_decision_owner_response_readback_snapshot() -> None: + snapshot = load_latest_ai_agent_result_capture_release_decision_owner_response_readback() + + assert snapshot["schema_version"] == "ai_agent_result_capture_release_decision_owner_response_readback_v1" + assert snapshot["program_status"]["current_task_id"] == "P2-144" + assert snapshot["program_status"]["next_task_id"] == "P2-145" + assert snapshot["program_status"]["overall_completion_percent"] == 100 + assert snapshot["program_status"]["runtime_authority"] == ( + "result_capture_release_decision_owner_response_readback_only_no_live_write" + ) + + rollups = snapshot["rollups"] + assert rollups["response_readback_lane_count"] == 5 + assert rollups["required_owner_field_count"] == 18 + assert rollups["readback_validation_check_count"] == 6 + assert rollups["readback_rejection_guard_count"] == 6 + assert rollups["operator_action_count"] == 5 + assert rollups["waiting_external_response_count"] == 5 + assert rollups["no_external_response_received_count"] == 5 + assert rollups["owner_response_received_count"] == 0 + assert rollups["owner_response_accepted_count"] == 0 + assert rollups["owner_response_rejected_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_readback_truth_keeps_all_runtime_gates_closed() -> None: + snapshot = load_latest_ai_agent_result_capture_release_decision_owner_response_readback() + truth = snapshot["owner_response_readback_truth"] + + assert truth["p2_143_preflight_loaded"] is True + assert truth["p2_142_war_room_baseline_preserved"] is True + assert truth["owner_response_readback_ready"] is True + assert truth["readback_only_mode"] is True + assert truth["no_external_response_received"] 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_readback_lane(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_decision_owner_response_readback()) + snapshot["response_readback_lanes"] = snapshot["response_readback_lanes"][:-1] + snapshot["rollups"]["response_readback_lane_count"] = 4 + snapshot["rollups"]["waiting_external_response_count"] = 4 + snapshot["rollups"]["no_external_response_received_count"] = 4 + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="response readback lanes ids mismatch"): + load_latest_ai_agent_result_capture_release_decision_owner_response_readback(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_readback()) + snapshot["owner_response_readback_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_readback(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_readback()) + 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_readback(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_readback()) + 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_readback(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_readback()) + 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_readback(tmp_path) + + +def _write_snapshot(directory: Path, payload: dict) -> None: + path = directory / "ai_agent_result_capture_release_decision_owner_response_readback_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_readback_api.py b/apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_readback_api.py new file mode 100644 index 000000000..7f647ff1e --- /dev/null +++ b/apps/api/tests/test_ai_agent_result_capture_release_decision_owner_response_readback_api.py @@ -0,0 +1,53 @@ +from __future__ import annotations + +from fastapi.testclient import TestClient + +from src.main import app + + +def test_release_decision_owner_response_readback_endpoint() -> None: + client = TestClient(app) + + response = client.get("/api/v1/agents/agent-result-capture-release-decision-owner-response-readback") + + assert response.status_code == 200 + payload = response.json() + assert payload["schema_version"] == "ai_agent_result_capture_release_decision_owner_response_readback_v1" + assert payload["program_status"]["current_task_id"] == "P2-144" + assert payload["program_status"]["next_task_id"] == "P2-145" + assert payload["program_status"]["overall_completion_percent"] == 100 + assert payload["program_status"]["runtime_authority"] == ( + "result_capture_release_decision_owner_response_readback_only_no_live_write" + ) + assert payload["prior_owner_response_preflight"]["schema_version"] == ( + "ai_agent_result_capture_release_decision_owner_response_preflight_v1" + ) + assert payload["prior_owner_response_preflight"]["next_task_id"] == "P2-144" + assert payload["rollups"]["response_readback_lane_count"] == 5 + assert payload["rollups"]["required_owner_field_count"] == 18 + assert payload["rollups"]["readback_validation_check_count"] == 6 + assert payload["rollups"]["readback_rejection_guard_count"] == 6 + assert payload["rollups"]["operator_action_count"] == 5 + assert payload["rollups"]["waiting_external_response_count"] == 5 + assert payload["rollups"]["no_external_response_received_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_readback_lanes"][0] + assert owner_lane["readback_id"] == "owner_release_response_readback" + assert owner_lane["source_lane_id"] == "owner_release_response_preflight" + assert owner_lane["readback_status"] == "no_external_response_received" + 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 fb7839394..0443757a3 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -6330,6 +6330,45 @@ "runtimeWriteAllowed": "runtime 寫入允許={value}" } }, + "resultCaptureReleaseDecisionOwnerResponseReadback": { + "title": "P2-144 Owner response 回讀狀態", + "source": "產生 {generated};目前 {current};下一步 {next}", + "priorTitle": "P2-143 預檢基線", + "truthTitle": "Owner response 回讀真相", + "laneTitle": "回覆讀回 lane", + "guardTitle": "讀回拒收規則", + "actionTitle": "操作員回讀事項", + "metrics": { + "overall": "完成度", + "lanes": "回讀 lane", + "requiredFields": "必填欄位", + "validationChecks": "讀回檢查", + "rejectionGuards": "拒收規則", + "actions": "操作選項", + "waiting": "等待回覆", + "noResponse": "未收件 lane", + "received": "已收 / 已接受", + "liveWrites": "正式寫入 / 發送" + }, + "flags": { + "p2Loaded": "已載入 P2-143={value}", + "readbackOnly": "只做回讀={value}", + "noExternalResponse": "尚無外部回覆={value}" + }, + "labels": { + "priorCurrent": "上一關目前={value}", + "priorNext": "上一關下一步={value}", + "ownerReceived": "owner 回覆收件={value}", + "redactedPayload": "遮罩 payload 納入={value}", + "gatewayWrites": "Gateway 寫入={value}", + "telegramSends": "Telegram 送出={value}", + "productionWrites": "正式寫入={value}", + "requiredFields": "必填欄位={value}", + "received": "已收件={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 fb7839394..0443757a3 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -6330,6 +6330,45 @@ "runtimeWriteAllowed": "runtime 寫入允許={value}" } }, + "resultCaptureReleaseDecisionOwnerResponseReadback": { + "title": "P2-144 Owner response 回讀狀態", + "source": "產生 {generated};目前 {current};下一步 {next}", + "priorTitle": "P2-143 預檢基線", + "truthTitle": "Owner response 回讀真相", + "laneTitle": "回覆讀回 lane", + "guardTitle": "讀回拒收規則", + "actionTitle": "操作員回讀事項", + "metrics": { + "overall": "完成度", + "lanes": "回讀 lane", + "requiredFields": "必填欄位", + "validationChecks": "讀回檢查", + "rejectionGuards": "拒收規則", + "actions": "操作選項", + "waiting": "等待回覆", + "noResponse": "未收件 lane", + "received": "已收 / 已接受", + "liveWrites": "正式寫入 / 發送" + }, + "flags": { + "p2Loaded": "已載入 P2-143={value}", + "readbackOnly": "只做回讀={value}", + "noExternalResponse": "尚無外部回覆={value}" + }, + "labels": { + "priorCurrent": "上一關目前={value}", + "priorNext": "上一關下一步={value}", + "ownerReceived": "owner 回覆收件={value}", + "redactedPayload": "遮罩 payload 納入={value}", + "gatewayWrites": "Gateway 寫入={value}", + "telegramSends": "Telegram 送出={value}", + "productionWrites": "正式寫入={value}", + "requiredFields": "必填欄位={value}", + "received": "已收件={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 51d2c2edc..b36b22dda 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 @@ -92,6 +92,7 @@ import { type AiAgentResultCaptureReleaseDecisionNextHandoffSnapshot, type AiAgentResultCaptureReleaseDecisionInputPrepSnapshot, type AiAgentResultCaptureReleaseDecisionOwnerResponsePreflightSnapshot, + type AiAgentResultCaptureReleaseDecisionOwnerResponseReadbackSnapshot, type AiAgentResultCaptureReleaseVerifierPreflightGateSnapshot, type AiAgentResultCaptureReleaseVerifierOwnerReviewPacketSnapshot, type AiAgentResultCaptureWriterImplementationReviewSnapshot, @@ -517,6 +518,7 @@ export function AutomationInventoryTab() { const [resultCaptureReleaseDecisionNextHandoff, setResultCaptureReleaseDecisionNextHandoff] = useState(null) const [resultCaptureReleaseDecisionInputPrep, setResultCaptureReleaseDecisionInputPrep] = useState(null) const [resultCaptureReleaseDecisionOwnerResponsePreflight, setResultCaptureReleaseDecisionOwnerResponsePreflight] = useState(null) + const [resultCaptureReleaseDecisionOwnerResponseReadback, setResultCaptureReleaseDecisionOwnerResponseReadback] = useState(null) const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState(null) const [ownerDryRunPackage, setOwnerDryRunPackage] = useState(null) const [hostStatefulInventory, setHostStatefulInventory] = useState(null) @@ -597,6 +599,7 @@ export function AutomationInventoryTab() { apiClient.getAiAgentResultCaptureReleaseDecisionNextHandoff(), apiClient.getAiAgentResultCaptureReleaseDecisionInputPrep(), apiClient.getAiAgentResultCaptureReleaseDecisionOwnerResponsePreflight(), + apiClient.getAiAgentResultCaptureReleaseDecisionOwnerResponseReadback(), apiClient.getAiAgentReportTruthActionabilityReview(), apiClient.getAiAgentOwnerApprovedFixtureDryRun(), apiClient.getAiAgentHostStatefulVersionInventory(), @@ -676,6 +679,7 @@ export function AutomationInventoryTab() { resultCaptureReleaseDecisionNextHandoffResult, resultCaptureReleaseDecisionInputPrepResult, resultCaptureReleaseDecisionOwnerResponsePreflightResult, + resultCaptureReleaseDecisionOwnerResponseReadbackResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -752,6 +756,7 @@ export function AutomationInventoryTab() { setResultCaptureReleaseDecisionNextHandoff(resultCaptureReleaseDecisionNextHandoffResult.status === 'fulfilled' ? resultCaptureReleaseDecisionNextHandoffResult.value : null) setResultCaptureReleaseDecisionInputPrep(resultCaptureReleaseDecisionInputPrepResult.status === 'fulfilled' ? resultCaptureReleaseDecisionInputPrepResult.value : null) setResultCaptureReleaseDecisionOwnerResponsePreflight(resultCaptureReleaseDecisionOwnerResponsePreflightResult.status === 'fulfilled' ? resultCaptureReleaseDecisionOwnerResponsePreflightResult.value : null) + setResultCaptureReleaseDecisionOwnerResponseReadback(resultCaptureReleaseDecisionOwnerResponseReadbackResult.status === 'fulfilled' ? resultCaptureReleaseDecisionOwnerResponseReadbackResult.value : null) setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null) setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null) setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null) @@ -826,6 +831,7 @@ export function AutomationInventoryTab() { resultCaptureReleaseDecisionNextHandoffResult, resultCaptureReleaseDecisionInputPrepResult, resultCaptureReleaseDecisionOwnerResponsePreflightResult, + resultCaptureReleaseDecisionOwnerResponseReadbackResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -2081,7 +2087,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 || !resultCaptureReleaseDecisionOwnerResponsePreflight || !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 || !resultCaptureReleaseDecisionOwnerResponseReadback || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { return (
@@ -3514,6 +3520,33 @@ export function AutomationInventoryTab() { + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.playbook_trust_write_count + resultCaptureReleaseDecisionOwnerResponsePreflight.rollups.production_write_count ) + const resultCaptureReleaseDecisionOwnerResponseReadbackOverall = resultCaptureReleaseDecisionOwnerResponseReadback.program_status.overall_completion_percent + const resultCaptureReleaseDecisionOwnerResponseReadbackLanes = resultCaptureReleaseDecisionOwnerResponseReadback.rollups.response_readback_lane_count + const resultCaptureReleaseDecisionOwnerResponseReadbackFields = resultCaptureReleaseDecisionOwnerResponseReadback.rollups.required_owner_field_count + const resultCaptureReleaseDecisionOwnerResponseReadbackChecks = resultCaptureReleaseDecisionOwnerResponseReadback.rollups.readback_validation_check_count + const resultCaptureReleaseDecisionOwnerResponseReadbackGuards = resultCaptureReleaseDecisionOwnerResponseReadback.rollups.readback_rejection_guard_count + const resultCaptureReleaseDecisionOwnerResponseReadbackActions = resultCaptureReleaseDecisionOwnerResponseReadback.rollups.operator_action_count + const resultCaptureReleaseDecisionOwnerResponseReadbackWaiting = resultCaptureReleaseDecisionOwnerResponseReadback.rollups.waiting_external_response_count + const resultCaptureReleaseDecisionOwnerResponseReadbackNoResponse = resultCaptureReleaseDecisionOwnerResponseReadback.rollups.no_external_response_received_count + const resultCaptureReleaseDecisionOwnerResponseReadbackReceived = ( + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.owner_response_received_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.owner_response_accepted_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.redacted_payload_ingested_count + ) + const resultCaptureReleaseDecisionOwnerResponseReadbackLiveWrites = ( + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.writer_apply_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.execution_apply_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.receipt_write_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.reviewer_queue_write_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.gateway_queue_write_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.telegram_send_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.bot_api_call_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.report_receipt_write_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.result_capture_write_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.learning_write_count + + resultCaptureReleaseDecisionOwnerResponseReadback.rollups.playbook_trust_write_count + + resultCaptureReleaseDecisionOwnerResponseReadback.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 @@ -8219,6 +8252,131 @@ export function AutomationInventoryTab() {
+
+
+
+ + + {t('resultCaptureReleaseDecisionOwnerResponseReadback.title')} + +
+ +
+ +
+ } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> +
+ +
+
+ {t('resultCaptureReleaseDecisionOwnerResponseReadback.priorTitle')} +

+ {resultCaptureReleaseDecisionOwnerResponseReadback.prior_owner_response_preflight.readiness_note} +

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

+ {resultCaptureReleaseDecisionOwnerResponseReadback.owner_response_readback_truth.truth_note} +

+
+ + + + + + + + +
+
+
+ + {t('resultCaptureReleaseDecisionOwnerResponseReadback.laneTitle')} +
+ {resultCaptureReleaseDecisionOwnerResponseReadback.response_readback_lanes.slice(0, 5).map(lane => ( +
+
+ + {lane.display_name} + + +
+ + {lane.readback_summary} + +
+ + + + + + +
+
+ ))} +
+ +
+ {resultCaptureReleaseDecisionOwnerResponseReadback.readback_rejection_guards.slice(0, 6).map(guard => ( +
+ {t('resultCaptureReleaseDecisionOwnerResponseReadback.guardTitle')} + + {guard.guard_id} + + + {guard.reason} + + +
+ ))} +
+ + {t('resultCaptureReleaseDecisionOwnerResponseReadback.actionTitle')} +
+ {resultCaptureReleaseDecisionOwnerResponseReadback.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 6034e0eba..9dff42d58 100644 --- a/apps/web/src/lib/api-client.ts +++ b/apps/web/src/lib/api-client.ts @@ -624,6 +624,11 @@ export const apiClient = { return handleResponse(res) }, + async getAiAgentResultCaptureReleaseDecisionOwnerResponseReadback() { + const res = await fetch(`${API_BASE_URL}/agents/agent-result-capture-release-decision-owner-response-readback`) + return handleResponse(res) + }, + async getAiAgentOwnerApprovedFixtureDryRun() { const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`) return handleResponse(res) @@ -9949,8 +9954,8 @@ export interface AiAgentResultCaptureReleaseDecisionOwnerResponsePreflightSnapsh 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: 'result_capture_release_decision_owner_response_preflight_only_no_live_write' status_note: string @@ -10042,6 +10047,128 @@ export interface AiAgentResultCaptureReleaseDecisionOwnerResponsePreflightSnapsh } } +interface AiAgentReleaseDecisionOwnerResponseReadbackLane { + readback_id: string + display_name: string + source_lane_id: string + owner_agent: string + current_task_id: string + target_next_task_id: string + readback_status: string + required_fields: string[] + readback_summary: string + response_received: boolean + response_accepted: boolean + response_rejected: boolean + redacted_payload_ingested: boolean + runtime_write_allowed: boolean + telegram_send_allowed: boolean + evidence_hash?: string +} + +export interface AiAgentResultCaptureReleaseDecisionOwnerResponseReadbackSnapshot { + schema_version: 'ai_agent_result_capture_release_decision_owner_response_readback_v1' + generated_at: string + program_status: { + overall_completion_percent: number + current_priority: 'P0' | 'P1' | 'P2' | 'P3' + current_task_id: 'P2-144' + next_task_id: 'P2-145' + read_only_mode: true + runtime_authority: 'result_capture_release_decision_owner_response_readback_only_no_live_write' + status_note: string + } + source_refs: string[] + prior_owner_response_preflight: AiAgentReleaseDecisionNextHandoffZeroCounts & { + schema_version: string + current_task_id: string + next_task_id: string + 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 + readiness_note: string + owner_response_received_count: number + owner_response_accepted_count: number + owner_response_rejected_count: number + redacted_payload_ingested_count: number + } + owner_response_readback_truth: AiAgentReleaseDecisionNextHandoffZeroCounts & { + p2_143_preflight_loaded: boolean + p2_142_war_room_baseline_preserved: boolean + owner_response_readback_ready: boolean + readback_only_mode: boolean + no_external_response_received: boolean + no_raw_payload_required: boolean + redaction_contract_loaded: boolean + rejection_policy_preserved: 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_readback_lanes: AiAgentReleaseDecisionOwnerResponseReadbackLane[] + readback_validation_checks: { + check_id: string + status: string + requirement: string + runtime_write_allowed: boolean + }[] + readback_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_readback_lane_count: number + required_owner_field_count: number + readback_validation_check_count: number + readback_rejection_guard_count: number + operator_action_count: number + waiting_external_response_count: number + no_external_response_received_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 1f3bcae3e..3e7014333 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,34 @@ +## 2026-06-14|P2-144 Owner response 回讀狀態本地完成 + +**背景**:P2-143 owner response preflight 已正式驗證完成;本輪承接 `P2-143 -> P2-144`,建立 owner response readback,只讀回外部正式回覆是否已收到與是否可進下一關。此階段仍不是正式收件、不是批准、不是 release authorization,也不開 reviewer / Gateway / Telegram / Bot API / result capture / learning / PlayBook trust / production writer。 + +**完成項目**: +- 新增 `ai_agent_result_capture_release_decision_owner_response_readback_v1` committed snapshot、service guard、API endpoint `GET /api/v1/agents/agent-result-capture-release-decision-owner-response-readback`、API/service tests、API client 型別與 governance automation inventory P2-144 區塊。 +- P2-144 snapshot 固定 response readback lane `5`、required owner field `18`、readback validation check `6`、readback rejection guard `6`、operator action `5`、waiting external response `5`、no external response received lane `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-144 卡片,顯示 P2-143 預檢基線、回讀真相、五條回覆讀回 lane、拒收規則與操作員回讀事項;前端只顯示產品化資安狀態與遮罩 evidence hash,不放非公開工作溝通內容。 + +**本地驗證**: +- JSON parse:P2-144 snapshot、`zh-TW.json`、`en.json` 通過。 +- Python 編譯:P2-144 loader 與 `agents.py` 通過。 +- API/service pytest:P2-139 至 P2-144 release decision chain regression `45 passed`;rebase 到 AwoooP Tenants 全域資產納管 commit 後,含 tenants regression 的推送前回歸 `47 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=807`、`git diff --check` 通過。 +- P2-144 snapshot / messages value-only 禁用外露值掃描:`forbidden_value_hits=0`;`zh-TW` / `en` i18n key parity:`11998 / 11998`,missing `0 / 0`。 + +**安全邊界**: +- P2-144 仍只是 owner response readback;不得把 readback、UI 可見、AwoooP approval、CD success、API 回傳或 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-144 owner response readback local slice:`100%`。 +- P2-144 production verification:`0%`。 +- active runtime gate、Telegram 實發、reviewer / Gateway queue write、production write 仍維持 `0`。 + +**下一步**: +- 推送 feature commit;等待 Gitea code-review / CD,deploy marker 生效後執行 production API readback、desktop / mobile smoke 與水平溢位檢查。 +- 正式驗證通過後,`P2-145` 才能承接 owner response acceptance gate;仍不得接收未遮罩 payload 或開 runtime writer。 + ## 2026-06-14|AwoooP Tenants 全域產品 / 網站 / 專案納管本地完成 **背景**:統帥指出 `/zh-TW/awooop/tenants` 沒有把所有網站、專案、產品納入,頁面仍偏向 AwoooP 租戶資料表與 source-control owner response 範圍,無法作為 operator 進入全域資產狀況的入口。本輪接在 `gitea/main=30f2f490 docs(ops): record P2-143 recovery readback [skip ci]`,使用乾淨 worktree `/private/tmp/awoooi-tenants-global-assets-20260614`,不覆蓋 `/Users/ogt/awoooi` 的平行異動。 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 b50beeeb9..d6351fb73 100644 --- a/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md +++ b/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md @@ -12,12 +12,21 @@ | 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-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 已完成 production readback 與 desktop / mobile smoke,P2-143 owner response 預檢已完成 production readback 與 in-app browser smoke。runtime worker、DB migration、production Redis consumer group、canonical runtime readback、live query、runtime score、result capture write、Telegram 實發、delivery receipt E2E、live report delivery、reviewer queue write、Gateway queue write、AI analysis runtime、中低風險 auto worker、KM / LOGBOOK / audit DB / timeline / PlayBook trust 寫入、SDK / 付費服務仍未開 gate | `ai_agent_result_capture_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`、Gitea CD run `4232` success、production API readback、desktop / mobile in-app browser smoke;P2-143 feature commit `755b0a8d`、deploy marker `667d6329`、Gitea code-review `2961` / CD `2960` success、production API readback、desktop / mobile in-app browser smoke;MASTER §3.2.1b / §3.2.1d / §3.4.3 | +| OpenClaw / Hermes / NemoTron 主動溝通、學習與成長證據 | 100% | P2-401A 到 P2-144 已完成只讀證據面、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 預檢與 owner response 回讀;P2-141 基線與 S4.9 owner release packet 補強皆已正式驗證,P2-142 12-Agent War Room 已完成 production readback 與 desktop / mobile smoke,P2-143 owner response 預檢已完成 production readback 與 in-app browser smoke,P2-144 owner response 回讀已本地完成,production verification 待推送後補。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_readback_v1`、`GET /api/v1/agents/agent-result-capture-release-decision-owner-response-readback`、`docs/evaluations/ai_agent_result_capture_release_decision_owner_response_readback_2026-06-14.json`、5 個回覆讀回 lane、18 個 owner 必填欄位、6 個 readback validation check、6 個 rejection guard、5 個 operator action、等待外部回覆 `5`、未收件 lane `5`、正式寫入 / 發送 `0`;P2-142 feature commit `5de4b3f3`、deploy marker `1a2c9e36`、Gitea CD run `4232` success、production API readback、desktop / mobile in-app browser smoke;P2-143 feature commit `755b0a8d`、deploy marker `667d6329`、Gitea code-review `2961` / CD `2960` success、production API readback、desktop / mobile in-app browser smoke;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 區塊 / production API readback / desktop + mobile in-app browser smoke 已完成;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`、feature commit `5de4b3f3`、deploy marker `1a2c9e36`、Gitea CD run `4232` success、`/zh-TW/governance?tab=automation-inventory`、12 份 Codex sub-agent 只讀回饋 | | Owner response 預檢與拒收邊界 | 100% | P2-143 已完成正式部署與 production readback;承接 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`、feature commit `755b0a8d`、deploy marker `667d6329`、Gitea code-review `2961` / CD `2960` success、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` | +| Owner response 回讀狀態 | 100% | P2-144 已本地完成;承接 P2-143 preflight,只讀回五類外部回覆仍未收到、未接受、未拒絕、未保存;正式驗證待 feature commit 推送、Gitea code-review / CD 與 production smoke 後補 | `ai_agent_result_capture_release_decision_owner_response_readback_v1`、`GET /api/v1/agents/agent-result-capture-release-decision-owner-response-readback`、5 個 response readback lane、18 個 required owner field、6 個 readback validation check、6 個 readback rejection guard、5 個 operator action、waiting external response `5`、no external response received `5`;owner response received / accepted / redacted payload / reviewer queue / Gateway / Telegram / Bot API / production write / secret read / destructive operation 全為 `0` | | 本工作清單與分析報告 | 100% | 已完成 | 本 MD 文件 | +### 2026-06-14 15:05 狀態同步 + +- `P2-144` owner response 回讀狀態已本地完成:新增 `ai_agent_result_capture_release_decision_owner_response_readback_v1`、`GET /api/v1/agents/agent-result-capture-release-decision-owner-response-readback`、治理頁 P2-144 區塊與繁中 UI 文案。 +- P2-144 承接 P2-143 預檢基線,固定 5 個 response readback lane、18 個 required owner field、6 個 readback validation check、6 個 readback rejection guard、5 個 operator action、5 個 waiting external response、5 個 no external response received lane。 +- 本地證據:P2-144 JSON parse、Python compile 通過;P2-139 至 P2-144 release decision chain regression `45 passed`,rebase 後含 tenants regression 的推送前回歸 `47 passed`;Web typecheck、source-control owner response guard、security mirror progress guard、doc secret sanity、value-only 禁用外露值掃描 `0`、i18n key parity `11998 / 11998` 與 diff check 通過;production verification 仍待推送後補。 +- 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 / false`。 +- P2-144 本地完成度 `100%`;production verification `0%`;下一步是推送 feature commit、等待 Gitea code-review / CD 後補 production API readback 與 desktop / mobile smoke。 + ### 2026-06-14 14:48 狀態同步 - `P2-143` owner response 預檢與拒收邊界已完成正式部署與 production readback:feature commit `755b0a8d`、deploy marker `667d6329 chore(cd): deploy 755b0a8 [skip ci]`。 @@ -194,9 +203,9 @@ AI Agent 自動化工作包目前完成度:**99.8%**。本工作清單文件 三 Agent 佈建布局目前完成度:**45%**。第一波已完成只讀 schema / snapshot / API / 測試 / 報告,第二波已接入治理頁自動化盤點 UI;正式 runtime 佈署、Telegram E2E 發送與 AgentSession 工作流仍需逐項 gate。 -三 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 已由 deploy marker `1a2c9e36` 完成 production smoke;P2-143 已由 feature commit `755b0a8d`、deploy marker `667d6329`、production API readback 與 desktop / mobile smoke 完成正式驗證。目前 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-144` owner response readback;不得開啟 runtime writer、Gateway queue、Telegram send、Bot API 或 production write。 +三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。P2-403A 到 P2-144 已把互動證據、報表治理、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 預檢與 owner response 回讀固定成可驗證證據。P2-141 基線已由 feature commit `ee5bf500` 與 deploy marker `306657fd` 正式驗證,S4.9 owner 欄位補強已由 commit `77515bbe` 與 deploy marker `a1ad68b9` 正式驗證;P2-142 已由 deploy marker `1a2c9e36` 完成 production smoke;P2-143 已由 feature commit `755b0a8d`、deploy marker `667d6329`、production API readback 與 desktop / mobile smoke 完成正式驗證;P2-144 已本地完成,正式驗證待推送與 CD 後補。目前 live AgentSession、Agent message、handoff、canonical runtime readback、live query、runtime score、result capture write、learning write、Telegram receipt、Gateway queue write、reviewer queue write、runtime verifier execution、live report delivery、AI analysis runtime、中低風險 auto worker、Telegram 實發、shadow worker live、delivery receipt E2E、KM / LOGBOOK / audit DB / timeline / PlayBook trust runtime 寫入仍全部為 `0`。真正下一步是 `P2-145` owner response acceptance gate;不得開啟 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-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-144 owner response readback;外部 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-144` 已補互動、學習證據面、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 預檢與 owner response 回讀。下一步是 P2-145 owner response acceptance gate;外部 registry / package source / host probe / SSH / kubectl / 工具安裝 / CI 變更 / 實際 PR creation / Telegram 實發與 learning write 仍需 gate。 完成度計算模型: @@ -1190,6 +1199,7 @@ UI: | 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;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 目標掃描通過;production API readback、desktop / mobile smoke、水平溢位 `0`、危險控制 `0`、工作溝通片語命中 `0` 已完成;不得把 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;feature commit `755b0a8d`、deploy marker `667d6329`;承接 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 通過;production API readback、desktop / mobile smoke、水平溢位 `0`、危險控制 `0`、工作溝通片語命中 `0` 已完成;owner response received / accepted / redacted payload / reviewer queue / Gateway / Telegram / Bot API / result capture / learning / PlayBook trust / production write / secret read / destructive operation 全為 `0`;下一關為 P2-144 owner response readback | +| P2-144 | 本地完成 | 100 | OpenClaw + Hermes + NemoTron | owner response 回讀狀態 | `ai_agent_result_capture_release_decision_owner_response_readback_v1` / snapshot / 只讀 API / governance UI;承接 P2-143 preflight,固定 5 個 response readback lane、18 個 required owner field、6 個 readback validation check、6 個 readback rejection guard、5 個 operator action、5 個 waiting external response、5 個 no external response received lane;runtime authority 固定 `result_capture_release_decision_owner_response_readback_only_no_live_write` | 本地 P2-139 至 P2-144 regression `45 passed`、rebase 後含 tenants regression 的推送前回歸 `47 passed`、JSON parse、Python compile、Web typecheck、source-control owner response guard、security mirror progress guard、doc secret sanity、value-only 禁用外露值掃描 `0`、i18n key parity `11998 / 11998` 與 diff check 通過;production API readback 與 desktop / mobile smoke 待補;owner response received / accepted / redacted payload / reviewer queue / Gateway / Telegram / Bot API / result capture / learning / PlayBook trust / production write / secret read / destructive operation 全為 `0`;下一關為 P2-145 owner response acceptance gate | ### P3 - 候選 Agent 擴展 diff --git a/docs/evaluations/ai_agent_result_capture_release_decision_owner_response_readback_2026-06-14.json b/docs/evaluations/ai_agent_result_capture_release_decision_owner_response_readback_2026-06-14.json new file mode 100644 index 000000000..cb985ed6c --- /dev/null +++ b/docs/evaluations/ai_agent_result_capture_release_decision_owner_response_readback_2026-06-14.json @@ -0,0 +1,408 @@ +{ + "schema_version": "ai_agent_result_capture_release_decision_owner_response_readback_v1", + "generated_at": "2026-06-14T15:05:00+08:00", + "program_status": { + "overall_completion_percent": 100, + "current_priority": "P2", + "current_task_id": "P2-144", + "next_task_id": "P2-145", + "read_only_mode": true, + "runtime_authority": "result_capture_release_decision_owner_response_readback_only_no_live_write", + "status_note": "P2-144 只讀回 P2-143 owner response 預檢後的外部回覆狀態;目前仍未收到、未接受、未拒絕、未保存任何正式 owner response,也不寫 reviewer queue、Gateway queue、Telegram、Bot API、result capture、learning、PlayBook trust 或 production target。" + }, + "source_refs": [ + "docs/evaluations/ai_agent_result_capture_release_decision_owner_response_preflight_2026-06-14.json", + "docs/evaluations/ai_agent_12_agent_war_room_2026-06-14.json", + "docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md#64-建立-owner-response-preflight-與拒收邊界", + "docs/HARD_RULES.md#iwooos-security-governance" + ], + "prior_owner_response_preflight": { + "schema_version": "ai_agent_result_capture_release_decision_owner_response_preflight_v1", + "current_task_id": "P2-143", + "next_task_id": "P2-144", + "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, + "readiness_note": "P2-143 已固定五條 owner response 預檢 lane、18 個必填欄位、6 個驗證檢查與 6 個拒收規則;P2-144 只能讀回外部回覆狀態,不得接收未遮罩 payload、不得啟動收件寫入或 runtime writer。", + "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 + }, + "owner_response_readback_truth": { + "p2_143_preflight_loaded": true, + "p2_142_war_room_baseline_preserved": true, + "owner_response_readback_ready": true, + "readback_only_mode": true, + "no_external_response_received": true, + "no_raw_payload_required": true, + "redaction_contract_loaded": true, + "rejection_policy_preserved": true, + "truth_note": "P2-144 只把 P2-143 的預檢結果讀回成可查詢狀態;五條 lane 都仍等待外部正式回覆,沒有收件、沒有驗證通過、沒有授權、沒有寫入,也沒有通知發送。", + "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_readback_lanes": [ + { + "readback_id": "owner_release_response_readback", + "display_name": "Owner release 回覆讀回", + "source_lane_id": "owner_release_response_preflight", + "owner_agent": "openclaw", + "current_task_id": "P2-144", + "target_next_task_id": "P2-145", + "readback_status": "no_external_response_received", + "required_fields": [ + "owner_role_team", + "owner_decision", + "decision_reason", + "affected_scope", + "redacted_evidence_refs", + "followup_owner" + ], + "readback_summary": "尚未收到 owner release 正式回覆;仍只保留必填欄位與遮罩 refs 要求,不接受未遮罩資料或口頭批准補位。", + "response_received": false, + "response_accepted": false, + "response_rejected": false, + "redacted_payload_ingested": false, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:4c4de30c5f9f20147b4ee92510ade8f808814b2bf783124a836f3e8df44a8e16" + }, + { + "readback_id": "verifier_response_readback", + "display_name": "Verifier 回覆讀回", + "source_lane_id": "verifier_response_preflight", + "owner_agent": "openclaw", + "current_task_id": "P2-144", + "target_next_task_id": "P2-145", + "readback_status": "no_external_response_received", + "required_fields": ["verifier_scope", "verification_criteria", "failure_escalation"], + "readback_summary": "尚未收到 verifier scope / criteria / escalation 正式回覆;不得啟動 verifier runtime 或把頁面可見視為驗證通過。", + "response_received": false, + "response_accepted": false, + "response_rejected": false, + "redacted_payload_ingested": false, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:822be792c1883d029c97576cb84c51042528b77d8f9f46170c3f2ead1cf23355" + }, + { + "readback_id": "rollback_owner_response_readback", + "display_name": "Rollback owner 回覆讀回", + "source_lane_id": "rollback_owner_response_preflight", + "owner_agent": "hermes", + "current_task_id": "P2-144", + "target_next_task_id": "P2-145", + "readback_status": "no_external_response_received", + "required_fields": ["rollback_owner", "rollback_condition", "rollback_validation_plan"], + "readback_summary": "尚未收到 rollback owner、回滾條件或驗證計畫正式回覆;不得把 rollback owner 標記為已確認。", + "response_received": false, + "response_accepted": false, + "response_rejected": false, + "redacted_payload_ingested": false, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:17dca36d7eec6fd13fc5a5436653d887fe7e8afe25215e20174715d1ad1753ce" + }, + { + "readback_id": "maintenance_window_response_readback", + "display_name": "維護窗口回覆讀回", + "source_lane_id": "maintenance_window_response_preflight", + "owner_agent": "openclaw", + "current_task_id": "P2-144", + "target_next_task_id": "P2-145", + "readback_status": "no_external_response_received", + "required_fields": ["maintenance_window", "impact_scope", "notification_plan"], + "readback_summary": "尚未收到維護時間、影響範圍與通知計畫正式回覆;不得批准維護窗口或送出通知。", + "response_received": false, + "response_accepted": false, + "response_rejected": false, + "redacted_payload_ingested": false, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:c0063fbb479658bc2f615933d93728f8051b908e26ed1a9f7ce655a61278aa3f" + }, + { + "readback_id": "live_apply_response_readback", + "display_name": "正式套用回覆讀回", + "source_lane_id": "live_apply_response_preflight", + "owner_agent": "openclaw", + "current_task_id": "P2-144", + "target_next_task_id": "P2-145", + "readback_status": "no_external_response_received", + "required_fields": ["live_apply_strategy", "stop_condition", "acceptance_evidence"], + "readback_summary": "尚未收到正式套用策略、停止條件與驗收證據正式回覆;不得釋放 writer、execution apply 或 production write。", + "response_received": false, + "response_accepted": false, + "response_rejected": false, + "redacted_payload_ingested": false, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:ec2636f1073f76d875ea812d0daef269348ef538cf52bf37833f51d4da9cdfd0" + } + ], + "readback_validation_checks": [ + { + "check_id": "owner_response_receipt_absent", + "status": "waiting_for_owner_response", + "requirement": "五條 lane 都必須維持未收件狀態,直到外部正式回覆提供完整欄位與遮罩 evidence refs。", + "runtime_write_allowed": false + }, + { + "check_id": "redacted_payload_absent", + "status": "not_satisfied", + "requirement": "目前沒有任何遮罩 payload 被納入;未遮罩資料、敏感值或驗證標頭都不得保存。", + "runtime_write_allowed": false + }, + { + "check_id": "verifier_readback_absent", + "status": "not_satisfied", + "requirement": "尚未收到 verifier scope、criteria 與 failure escalation,因此不得啟動驗證或標記通過。", + "runtime_write_allowed": false + }, + { + "check_id": "rollback_and_window_readback_absent", + "status": "not_satisfied", + "requirement": "尚未收到 rollback owner 與 maintenance window 正式回覆,因此不得確認 rollback 或維護窗口。", + "runtime_write_allowed": false + }, + { + "check_id": "live_apply_readback_absent", + "status": "not_satisfied", + "requirement": "尚未收到 live apply strategy、stop condition 與 acceptance evidence,因此 writer 與 execution apply 必須關閉。", + "runtime_write_allowed": false + }, + { + "check_id": "approval_source_separation_preserved", + "status": "blocked_by_policy", + "requirement": "AwoooP approval、UI 可見、CD success 或 smoke pass 仍不得被視為 IwoooS 資安批准或 runtime 授權。", + "runtime_write_allowed": false + } + ], + "readback_rejection_guards": [ + { + "guard_id": "reject_readback_payload_with_sensitive_material", + "status": "active", + "reason": "回讀若包含敏感值、token、private key、cookie、驗證標頭、runner token、webhook secret 或未遮罩 runtime 資料,必須拒收並維持 0 寫入。", + "runtime_write_allowed": false + }, + { + "guard_id": "reject_readback_missing_required_owner_fields", + "status": "active", + "reason": "任何正式回覆缺 owner role / team、decision、reason、scope、遮罩 evidence refs 或 follow-up owner 時,不得進入下一關。", + "runtime_write_allowed": false + }, + { + "guard_id": "reject_readback_without_verifier_and_rollback", + "status": "active", + "reason": "缺 verifier、failure escalation、rollback owner、rollback condition 或 maintenance window 時,不得開 release gate。", + "runtime_write_allowed": false + }, + { + "guard_id": "reject_unredacted_evidence_readback", + "status": "active", + "reason": "evidence refs 必須是遮罩引用或雜湊摘要;可反推出敏感資料時必須拒收。", + "runtime_write_allowed": false + }, + { + "guard_id": "reject_runtime_execution_request", + "status": "active", + "reason": "回覆若要求直接 reload、restart、active scan、firewall / Nginx 變更、production apply 或任何 runtime 寫入,必須拒收並保留 gate 0。", + "runtime_write_allowed": false + }, + { + "guard_id": "reject_security_approval_confusion", + "status": "active", + "reason": "部署成功、治理頁卡片可見、候選可見或一般任務批准不得替代 IwoooS 資安 owner response。", + "runtime_write_allowed": false + } + ], + "operator_actions": [ + { + "action_id": "readback_owner_response_absence", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "讀回五條 owner response lane 仍未收到正式回覆;不得寫入 receipt 或 reviewer queue。", + "runtime_write_allowed": false + }, + { + "action_id": "readback_redacted_evidence_absence", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "確認目前只顯示遮罩摘要與 evidence hash;不得保存敏感值、驗證標頭或未遮罩 runtime 資料。", + "runtime_write_allowed": false + }, + { + "action_id": "readback_verifier_acceptance_gap", + "owner_agent": "openclaw", + "status": "approval_required", + "operator_instruction": "持續等待 verifier scope、criteria 與 failure escalation;不得啟動 verifier runtime。", + "runtime_write_allowed": false + }, + { + "action_id": "readback_rollback_window_gap", + "owner_agent": "hermes", + "status": "approval_required", + "operator_instruction": "持續等待 rollback owner、maintenance window 與 notification plan;不得批准維護窗口或送出通知。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_p2_145_owner_response_acceptance_gate", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "下一關只能準備 owner response acceptance gate;不得寫 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": "前端只能顯示回讀摘要、等待狀態、必填欄位、拒收規則、只讀 gate 與遮罩 evidence hash;不得顯示非公開溝通、未脫敏指令、推理草稿、敏感值、驗證標頭或未遮罩 runtime 資料。" + }, + "rollups": { + "response_readback_lane_count": 5, + "required_owner_field_count": 18, + "readback_validation_check_count": 6, + "readback_rejection_guard_count": 6, + "operator_action_count": 5, + "waiting_external_response_count": 5, + "no_external_response_received_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 439c6350d..488d52adc 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 @@ -681,6 +681,7 @@ Alert / Sentry / SigNoz / Gitea / Market Watch / Operator | `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 API readback、desktop / mobile smoke、水平溢位 `0`、危險控制 `0`、工作溝通片語命中 `0` 已完成,已由 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`;feature commit `755b0a8d`、deploy marker `667d6329`、Gitea code-review `2961` / CD `2960` success、本地 regression `37 passed`、JSON parse、Python compile、Web typecheck、guard、doc secret sanity、禁用外露值掃描、production API readback、desktop / mobile smoke、水平溢位 `0`、危險控制 `0`、工作溝通片語命中 `0` 已完成,下一步 P2-144 owner response readback | +| `docs/evaluations/ai_agent_result_capture_release_decision_owner_response_readback_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-decision-owner-response-readback` | P2-144 owner response readback;承接 P2-143 preflight,建立 5 條 response readback lane、18 個 required owner field、6 個 readback validation check、6 個 readback rejection guard、5 個 operator action、5 個 waiting external response 與 5 個 no external response received lane;runtime authority 固定 `result_capture_release_decision_owner_response_readback_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`;本地 P2-139 至 P2-144 regression `45 passed`,rebase 後含 tenants regression 的推送前回歸 `47 passed`、JSON parse、Python compile、Web typecheck、guard、doc secret sanity、value-only 禁用外露值掃描、i18n key parity 與 diff check 通過;production API readback 與 desktop / mobile smoke 待補,下一步 P2-145 owner response acceptance gate | | `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 主動營運委派與版本生命週期契約 @@ -813,6 +814,7 @@ Repo / registry / release notes / K8s / host / observability / backup evidence 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 API readback、desktop / mobile 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`;feature commit `755b0a8d`、deploy marker `667d6329`、Gitea code-review `2961` / CD `2960` success、本地 P2-142 War Room + P2-139 至 P2-143 regression `37 passed`、JSON parse、Python compile、Web typecheck、guard、doc secret sanity、禁用外露值掃描、production API readback 與 desktop / mobile smoke 通過。下一步 P2-144 owner response readback。 +65. 建立 owner response readback。🔄 P2-144 已本地完成;承接 P2-143 preflight,固定 response readback lane `5`、required owner field `18`、readback validation check `6`、readback rejection guard `6`、operator action `5`、waiting external response `5`、no external response received lane `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-139 至 P2-144 regression `45 passed`,rebase 後含 tenants regression 的推送前回歸 `47 passed`、JSON parse、Python compile、Web typecheck、guard、doc secret sanity、value-only 禁用外露值掃描、i18n key parity 與 diff check 通過;production API readback 與 desktop / mobile smoke 待補。下一步 P2-145 owner response acceptance gate。 #### 3.2.1d 2026-06-11 Agent 互動、學習與成長證據面