From ee5bf500ac78059957a4445617c4a92d1828c034 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 14 Jun 2026 13:21:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(governance):=20=E6=96=B0=E5=A2=9E=20releas?= =?UTF-8?q?e=20decision=20input=20prep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api/src/api/v1/agents.py | 33 ++ ...ult_capture_release_decision_input_prep.py | 342 ++++++++++++++++++ ...ult_capture_release_decision_input_prep.py | 99 +++++ ...capture_release_decision_input_prep_api.py | 32 ++ apps/web/messages/en.json | 35 ++ apps/web/messages/zh-TW.json | 35 ++ .../tabs/automation-inventory-tab.tsx | 148 +++++++- apps/web/src/lib/api-client.ts | 108 ++++++ docs/LOGBOOK.md | 33 ++ ...AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md | 16 +- ...elease_decision_input_prep_2026-06-14.json | 339 +++++++++++++++++ ...release_decision_input_prep_v1.schema.json | 286 +++++++++++++++ ...-04-15-MASTER-ai-autonomous-flywheel-v2.md | 10 + 13 files changed, 1512 insertions(+), 4 deletions(-) create mode 100644 apps/api/src/services/ai_agent_result_capture_release_decision_input_prep.py create mode 100644 apps/api/tests/test_ai_agent_result_capture_release_decision_input_prep.py create mode 100644 apps/api/tests/test_ai_agent_result_capture_release_decision_input_prep_api.py create mode 100644 docs/evaluations/ai_agent_result_capture_release_decision_input_prep_2026-06-14.json create mode 100644 docs/schemas/ai_agent_result_capture_release_decision_input_prep_v1.schema.json diff --git a/apps/api/src/api/v1/agents.py b/apps/api/src/api/v1/agents.py index b60c9e379..3ff67233b 100644 --- a/apps/api/src/api/v1/agents.py +++ b/apps/api/src/api/v1/agents.py @@ -130,6 +130,9 @@ from src.services.ai_agent_result_capture_release_decision_readback import ( from src.services.ai_agent_result_capture_release_decision_next_handoff import ( load_latest_ai_agent_result_capture_release_decision_next_handoff, ) +from src.services.ai_agent_result_capture_release_decision_input_prep import ( + load_latest_ai_agent_result_capture_release_decision_input_prep, +) from src.services.ai_agent_result_capture_owner_promotion_review import ( load_latest_ai_agent_result_capture_owner_promotion_review, ) @@ -2358,6 +2361,36 @@ async def get_agent_result_capture_release_decision_next_handoff() -> dict[str, ) from exc +@router.get( + "/agent-result-capture-release-decision-input-prep", + response_model=dict[str, Any], + summary="取得 AI Agent result capture release decision input prep", + description=( + "讀取最新已提交的 P2-141 release decision input prep;" + "此端點只把 P2-140 next handoff 轉成 owner / verifier 決策輸入準備包," + "不把準備包視為 owner approval、不核發 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_input_prep() -> dict[str, Any]: + """Return the latest read-only release decision input-prep package.""" + try: + payload = await asyncio.to_thread(load_latest_ai_agent_result_capture_release_decision_input_prep) + 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_input_prep_invalid", error=str(exc)) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="AI Agent result capture release decision input prep 無效", + ) 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_input_prep.py b/apps/api/src/services/ai_agent_result_capture_release_decision_input_prep.py new file mode 100644 index 000000000..66988699b --- /dev/null +++ b/apps/api/src/services/ai_agent_result_capture_release_decision_input_prep.py @@ -0,0 +1,342 @@ +""" +AI Agent result capture release decision input-prep snapshot. + +Loads the latest committed P2-141 decision input-prep package. This module only +turns P2-140 next-handoff evidence into owner / verifier decision input packets; +it never treats prepared inputs as approval, writes reviewer / Gateway queues, +sends Telegram messages, calls Bot APIs, writes result capture, writes learning +records, updates PlayBook trust, reads secrets, writes production targets, or +performs destructive operations. +""" + +from __future__ import annotations + +import json +import re +from pathlib import Path +from typing import Any + +from src.services.snapshot_paths import default_evaluations_dir + +_DEFAULT_EVALUATIONS_DIR = default_evaluations_dir(Path(__file__)) +_SNAPSHOT_PATTERN = "ai_agent_result_capture_release_decision_input_prep_*.json" +_SCHEMA_VERSION = "ai_agent_result_capture_release_decision_input_prep_v1" +_RUNTIME_AUTHORITY = "result_capture_release_decision_input_prep_only_no_live_write" + + +def load_latest_ai_agent_result_capture_release_decision_input_prep( + evaluations_dir: Path | None = None, +) -> dict[str, Any]: + """Load the newest committed release decision input-prep package.""" + 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 input prep 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_decision_input_packets(payload, label) + _require_blocked_transitions(payload, label) + _require_actions(payload, label) + _require_display_redaction(payload, label) + _require_no_forbidden_display_terms(payload, label) + _require_rollup_consistency(payload, label) + return payload + + +def _require_schema(payload: dict[str, Any], label: str) -> None: + if payload.get("schema_version") != _SCHEMA_VERSION: + raise ValueError(f"{label}: expected schema_version={_SCHEMA_VERSION}") + status = payload.get("program_status") or {} + expected = { + "current_priority": "P2", + "current_task_id": "P2-141", + "next_task_id": "P2-142", + "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_next_handoff") or {} + expected = { + "schema_version": "ai_agent_result_capture_release_decision_next_handoff_v1", + "current_task_id": "P2-140", + "next_task_id": "P2-141", + "next_gate_handoff_count": 5, + "stale_operator_action_count": 1, + "blocked_handoff_transition_count": 6, + "operator_action_count": 5, + "approval_required_subtotal": 12, + "blocked_and_critical_subtotal": 12, + } + expected.update(_zero_count_expectations()) + mismatches = _mismatches(prior, expected) + if mismatches: + raise ValueError(f"{label}: prior_next_handoff mismatch: {mismatches}") + if not prior.get("readiness_note"): + raise ValueError(f"{label}: prior_next_handoff.readiness_note is required") + + +def _require_truth(payload: dict[str, Any], label: str) -> None: + truth = payload.get("decision_input_truth") or {} + required_true = { + "p2_140_next_handoff_loaded", + "next_task_id_alignment_checked", + "stale_self_loop_containment_inherited", + "p2_141_input_prep_only", + "owner_input_packet_required", + "verifier_input_packet_required", + "rollback_input_packet_required", + "maintenance_window_input_required", + "live_apply_input_required", + "redaction_review_required", + } + missing = sorted(field for field in required_true if truth.get(field) is not True) + if missing: + raise ValueError(f"{label}: decision input flags must remain true: {missing}") + + required_false = { + "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}: decision input live/send/write flags must remain false: {unsafe}") + + non_zero = sorted(field for field in _zero_count_expectations() if truth.get(field) != 0) + if non_zero: + raise ValueError(f"{label}: decision input live counters must remain zero: {non_zero}") + if not truth.get("truth_note"): + raise ValueError(f"{label}: decision_input_truth.truth_note is required") + + +def _require_decision_input_packets(payload: dict[str, Any], label: str) -> None: + items = payload.get("decision_input_packets") or [] + _require_ids( + items, + "packet_id", + { + "decision_input_owner_release", + "decision_input_verifier", + "decision_input_rollback_owner", + "decision_input_maintenance_window", + "decision_input_live_apply", + }, + label, + "decision input packets", + ) + for item in items: + item_id = item.get("packet_id") + expected = { + "current_task_id": "P2-141", + "target_next_task_id": "P2-142", + "input_status": "missing_required_decision_input", + "approval_required": True, + "runtime_write_allowed": False, + "telegram_send_allowed": False, + } + mismatches = _mismatches(item, expected) + if mismatches: + raise ValueError(f"{label}: decision input packet {item_id} mismatch: {mismatches}") + if not item.get("required_input_type"): + raise ValueError(f"{label}: decision input packet {item_id}.required_input_type is required") + missing_fields = item.get("missing_fields") or [] + if not isinstance(missing_fields, list) or not missing_fields: + raise ValueError(f"{label}: decision input packet {item_id}.missing_fields is required") + if not item.get("input_summary"): + raise ValueError(f"{label}: decision input packet {item_id}.input_summary is required") + if not _is_redacted_sha256(item.get("evidence_hash")): + raise ValueError(f"{label}: decision input packet {item_id}.evidence_hash must be redacted sha256") + + +def _require_blocked_transitions(payload: dict[str, Any], label: str) -> None: + items = payload.get("blocked_input_transitions") or [] + _require_count(items, 6, label, "blocked input transitions") + for item in items: + item_id = item.get("transition_id") + if item.get("runtime_write_allowed") is not False: + raise ValueError(f"{label}: blocked input transition {item_id} must keep runtime_write_allowed=false") + if item.get("status") not in {"blocked_by_missing_input", "blocked_by_policy", "approval_required"}: + raise ValueError(f"{label}: blocked input transition {item_id} status is invalid") + if not item.get("reason"): + raise ValueError(f"{label}: blocked input transition {item_id}.reason is required") + + +def _require_actions(payload: dict[str, Any], label: str) -> None: + items = payload.get("operator_actions") or [] + _require_count(items, 5, label, "operator actions") + for item in items: + item_id = str(item.get("action_id")) + if "p2_139" in item_id or "p2_140" in item_id: + raise ValueError(f"{label}: operator action {item_id} must not point back to P2-139/P2-140") + 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 {} + missing_input_field_count = sum(len(item.get("missing_fields") or []) for item in payload.get("decision_input_packets") or []) + expected = { + "decision_input_packet_count": len(payload.get("decision_input_packets") or []), + "owner_input_packet_count": 1, + "verifier_input_packet_count": 1, + "rollback_input_packet_count": 1, + "maintenance_window_input_count": 1, + "live_apply_input_count": 1, + "missing_input_field_count": missing_input_field_count, + "blocked_input_transition_count": len(payload.get("blocked_input_transitions") or []), + "operator_action_count": len(payload.get("operator_actions") or []), + "approval_required_subtotal": 12, + "blocked_and_critical_subtotal": 12, + "stale_operator_action_count": 1, + } + expected.update(_zero_count_expectations()) + mismatches = _mismatches(rollups, expected) + if mismatches: + raise ValueError(f"{label}: rollups mismatch: {mismatches}") + + +def _require_no_forbidden_display_terms(payload: Any, label: str) -> None: + forbidden = { + "work_window_transcript", + "internal_collaboration_transcript", + "raw_prompt", + "private_reasoning", + "chain_of_thought", + "authorization_header", + "secret_value", + } + found = sorted(term for term in forbidden if _contains_term(payload, term)) + if found: + raise ValueError(f"{label}: forbidden display terms leaked: {found}") + + +def _contains_term(value: Any, term: str) -> bool: + if isinstance(value, str): + return term.lower() in value.lower() + if isinstance(value, dict): + return any(_contains_term(child, term) for child in value.values()) + if isinstance(value, list): + return any(_contains_term(child, term) for child in value) + return False + + +def _zero_count_expectations() -> 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_input_prep.py b/apps/api/tests/test_ai_agent_result_capture_release_decision_input_prep.py new file mode 100644 index 000000000..9ee1427c1 --- /dev/null +++ b/apps/api/tests/test_ai_agent_result_capture_release_decision_input_prep.py @@ -0,0 +1,99 @@ +from __future__ import annotations + +import copy +import json +from pathlib import Path + +import pytest + +from src.services.ai_agent_result_capture_release_decision_input_prep import ( + load_latest_ai_agent_result_capture_release_decision_input_prep, +) + + +def test_load_latest_release_decision_input_prep_snapshot() -> None: + snapshot = load_latest_ai_agent_result_capture_release_decision_input_prep() + + assert snapshot["schema_version"] == "ai_agent_result_capture_release_decision_input_prep_v1" + assert snapshot["program_status"]["current_task_id"] == "P2-141" + assert snapshot["program_status"]["next_task_id"] == "P2-142" + assert snapshot["program_status"]["overall_completion_percent"] == 100 + assert snapshot["program_status"]["runtime_authority"] == "result_capture_release_decision_input_prep_only_no_live_write" + + rollups = snapshot["rollups"] + assert rollups["decision_input_packet_count"] == 5 + assert rollups["missing_input_field_count"] == 15 + assert rollups["blocked_input_transition_count"] == 6 + assert rollups["operator_action_count"] == 5 + assert rollups["approval_required_subtotal"] == 12 + assert rollups["blocked_and_critical_subtotal"] == 12 + 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["result_capture_write_count"] == 0 + assert rollups["learning_write_count"] == 0 + assert rollups["playbook_trust_write_count"] == 0 + assert rollups["production_write_count"] == 0 + + +def test_decision_input_truth_does_not_grant_release_or_writes() -> None: + snapshot = load_latest_ai_agent_result_capture_release_decision_input_prep() + truth = snapshot["decision_input_truth"] + + assert truth["p2_140_next_handoff_loaded"] is True + assert truth["next_task_id_alignment_checked"] is True + assert truth["stale_self_loop_containment_inherited"] is True + assert truth["p2_141_input_prep_only"] is True + assert truth["owner_input_packet_required"] is True + assert truth["verifier_input_packet_required"] is True + 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_decision_input_packet(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_decision_input_prep()) + snapshot["decision_input_packets"] = snapshot["decision_input_packets"][:-1] + snapshot["rollups"]["decision_input_packet_count"] = 4 + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="decision input packets ids mismatch"): + load_latest_ai_agent_result_capture_release_decision_input_prep(tmp_path) + + +def test_rejects_packet_without_missing_fields(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_decision_input_prep()) + snapshot["decision_input_packets"][0]["missing_fields"] = [] + snapshot["rollups"]["missing_input_field_count"] = 12 + _write_snapshot(tmp_path, snapshot) + + with pytest.raises(ValueError, match="missing_fields is required"): + load_latest_ai_agent_result_capture_release_decision_input_prep(tmp_path) + + +def test_rejects_gateway_write_drift(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_decision_input_prep()) + 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_input_prep(tmp_path) + + +def test_rejects_forbidden_display_terms(tmp_path: Path) -> None: + snapshot = copy.deepcopy(load_latest_ai_agent_result_capture_release_decision_input_prep()) + 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_input_prep(tmp_path) + + +def _write_snapshot(directory: Path, payload: dict) -> None: + path = directory / "ai_agent_result_capture_release_decision_input_prep_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_input_prep_api.py b/apps/api/tests/test_ai_agent_result_capture_release_decision_input_prep_api.py new file mode 100644 index 000000000..d2e7189c6 --- /dev/null +++ b/apps/api/tests/test_ai_agent_result_capture_release_decision_input_prep_api.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +from fastapi.testclient import TestClient + +from src.main import app + + +def test_release_decision_input_prep_endpoint() -> None: + client = TestClient(app) + + response = client.get("/api/v1/agents/agent-result-capture-release-decision-input-prep") + + assert response.status_code == 200 + payload = response.json() + assert payload["schema_version"] == "ai_agent_result_capture_release_decision_input_prep_v1" + assert payload["program_status"]["current_task_id"] == "P2-141" + assert payload["program_status"]["next_task_id"] == "P2-142" + assert payload["program_status"]["overall_completion_percent"] == 100 + assert payload["program_status"]["runtime_authority"] == "result_capture_release_decision_input_prep_only_no_live_write" + assert payload["prior_next_handoff"]["schema_version"] == "ai_agent_result_capture_release_decision_next_handoff_v1" + assert payload["prior_next_handoff"]["next_task_id"] == "P2-141" + assert payload["rollups"]["decision_input_packet_count"] == 5 + assert payload["rollups"]["missing_input_field_count"] == 15 + assert payload["rollups"]["blocked_input_transition_count"] == 6 + assert payload["rollups"]["operator_action_count"] == 5 + assert payload["rollups"]["approval_required_subtotal"] == 12 + assert payload["rollups"]["blocked_and_critical_subtotal"] == 12 + 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 diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 74d20e22c..96d6b995c 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -6258,6 +6258,41 @@ "telegramSendAllowed": "Telegram 發送允許={value}" } }, + "resultCaptureReleaseDecisionInputPrep": { + "title": "P2-141 釋出決策輸入準備包", + "source": "產生 {generated};目前 {current};下一步 {next}", + "priorTitle": "P2-140 下一關交接基線", + "truthTitle": "決策輸入真相", + "packetTitle": "決策輸入準備卡", + "blockerTitle": "缺輸入阻擋", + "actionTitle": "操作員準備事項", + "metrics": { + "overall": "完成度", + "inputPackets": "準備包", + "nextHandoffs": "上一關交接", + "missingFields": "缺欄位", + "blockers": "已阻擋轉換", + "actions": "操作選項", + "approvalRequired": "仍需批准", + "blocked": "阻擋總數", + "liveWrites": "正式寫入 / 發送" + }, + "flags": { + "p2Loaded": "已載入 P2-140={value}", + "inputPrepOnly": "只準備輸入={value}", + "ownerRequired": "Owner 輸入必要={value}" + }, + "labels": { + "priorCurrent": "上一關目前={value}", + "priorNext": "上一關下一步={value}", + "gatewayWrites": "Gateway 寫入={value}", + "telegramSends": "Telegram 送出={value}", + "productionWrites": "正式寫入={value}", + "missingFields": "缺欄位={value}", + "runtimeWriteAllowed": "runtime 寫入允許={value}", + "telegramSendAllowed": "Telegram 發送允許={value}" + } + }, "resultCaptureReleaseVerifierOwnerReviewPacket": { "title": "P2-137 釋出驗證器負責人審查包", "source": "產生 {generated};目前 {current};下一步 {next}", diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 74d20e22c..96d6b995c 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -6258,6 +6258,41 @@ "telegramSendAllowed": "Telegram 發送允許={value}" } }, + "resultCaptureReleaseDecisionInputPrep": { + "title": "P2-141 釋出決策輸入準備包", + "source": "產生 {generated};目前 {current};下一步 {next}", + "priorTitle": "P2-140 下一關交接基線", + "truthTitle": "決策輸入真相", + "packetTitle": "決策輸入準備卡", + "blockerTitle": "缺輸入阻擋", + "actionTitle": "操作員準備事項", + "metrics": { + "overall": "完成度", + "inputPackets": "準備包", + "nextHandoffs": "上一關交接", + "missingFields": "缺欄位", + "blockers": "已阻擋轉換", + "actions": "操作選項", + "approvalRequired": "仍需批准", + "blocked": "阻擋總數", + "liveWrites": "正式寫入 / 發送" + }, + "flags": { + "p2Loaded": "已載入 P2-140={value}", + "inputPrepOnly": "只準備輸入={value}", + "ownerRequired": "Owner 輸入必要={value}" + }, + "labels": { + "priorCurrent": "上一關目前={value}", + "priorNext": "上一關下一步={value}", + "gatewayWrites": "Gateway 寫入={value}", + "telegramSends": "Telegram 送出={value}", + "productionWrites": "正式寫入={value}", + "missingFields": "缺欄位={value}", + "runtimeWriteAllowed": "runtime 寫入允許={value}", + "telegramSendAllowed": "Telegram 發送允許={value}" + } + }, "resultCaptureReleaseVerifierOwnerReviewPacket": { "title": "P2-137 釋出驗證器負責人審查包", "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 08633b2a1..b5058200e 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 @@ -89,6 +89,7 @@ import { type AiAgentResultCaptureReleaseDecisionHoldSnapshot, type AiAgentResultCaptureReleaseDecisionReadbackSnapshot, type AiAgentResultCaptureReleaseDecisionNextHandoffSnapshot, + type AiAgentResultCaptureReleaseDecisionInputPrepSnapshot, type AiAgentResultCaptureReleaseVerifierPreflightGateSnapshot, type AiAgentResultCaptureReleaseVerifierOwnerReviewPacketSnapshot, type AiAgentResultCaptureWriterImplementationReviewSnapshot, @@ -511,6 +512,7 @@ export function AutomationInventoryTab() { const [resultCaptureReleaseDecisionHold, setResultCaptureReleaseDecisionHold] = useState(null) const [resultCaptureReleaseDecisionReadback, setResultCaptureReleaseDecisionReadback] = useState(null) const [resultCaptureReleaseDecisionNextHandoff, setResultCaptureReleaseDecisionNextHandoff] = useState(null) + const [resultCaptureReleaseDecisionInputPrep, setResultCaptureReleaseDecisionInputPrep] = useState(null) const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState(null) const [ownerDryRunPackage, setOwnerDryRunPackage] = useState(null) const [hostStatefulInventory, setHostStatefulInventory] = useState(null) @@ -588,6 +590,7 @@ export function AutomationInventoryTab() { apiClient.getAiAgentResultCaptureReleaseDecisionHold(), apiClient.getAiAgentResultCaptureReleaseDecisionReadback(), apiClient.getAiAgentResultCaptureReleaseDecisionNextHandoff(), + apiClient.getAiAgentResultCaptureReleaseDecisionInputPrep(), apiClient.getAiAgentReportTruthActionabilityReview(), apiClient.getAiAgentOwnerApprovedFixtureDryRun(), apiClient.getAiAgentHostStatefulVersionInventory(), @@ -664,6 +667,7 @@ export function AutomationInventoryTab() { resultCaptureReleaseDecisionHoldResult, resultCaptureReleaseDecisionReadbackResult, resultCaptureReleaseDecisionNextHandoffResult, + resultCaptureReleaseDecisionInputPrepResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -737,6 +741,7 @@ export function AutomationInventoryTab() { setResultCaptureReleaseDecisionHold(resultCaptureReleaseDecisionHoldResult.status === 'fulfilled' ? resultCaptureReleaseDecisionHoldResult.value : null) setResultCaptureReleaseDecisionReadback(resultCaptureReleaseDecisionReadbackResult.status === 'fulfilled' ? resultCaptureReleaseDecisionReadbackResult.value : null) setResultCaptureReleaseDecisionNextHandoff(resultCaptureReleaseDecisionNextHandoffResult.status === 'fulfilled' ? resultCaptureReleaseDecisionNextHandoffResult.value : null) + setResultCaptureReleaseDecisionInputPrep(resultCaptureReleaseDecisionInputPrepResult.status === 'fulfilled' ? resultCaptureReleaseDecisionInputPrepResult.value : null) setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null) setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null) setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null) @@ -808,6 +813,7 @@ export function AutomationInventoryTab() { resultCaptureReleaseDecisionHoldResult, resultCaptureReleaseDecisionReadbackResult, resultCaptureReleaseDecisionNextHandoffResult, + resultCaptureReleaseDecisionInputPrepResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -2050,7 +2056,7 @@ export function AutomationInventoryTab() { ) } - if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !proactiveOperations || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportAutomationReview || !reportStatusBoard || !reportRuntimeReadiness || !reportRuntimeDryRun || !reportRuntimeFixtureReadback || !runtimeWorkerShadowGate || !operationPermissionModel || !candidateOperationDryRunEvidence || !taskResultAuditTrail || !matchedPlaybookLearningGap || !criticReviewerResultCapture || !ownerApprovedResultCaptureDryRun || !ownerApprovedResultCaptureReadback || !runtimeReadbackApprovalPackage || !runtimeReadbackImplementationReview || !reportLiveDeliveryApprovalPackage || !runtimeReadbackFixtureApproval || !runtimeReadbackPromotionGate || !ownerApprovedFixturePromotionGate || !canonicalRuntimeReadbackOwnerAcceptance || !failureReceiptNoSendReplay || !reviewerQueueNoWriteReadback || !resultCaptureNoWriteReadback || !resultCapturePromotionApprovalGate || !ownerApprovedResultCapturePromotionDryRun || !resultCaptureWriteGateReview || !resultCaptureWriterImplementationReview || !resultCaptureWriterDryRunFixture || !resultCaptureWriterDryRunReadback || !resultCaptureOwnerPromotionReview || !resultCaptureOwnerApprovedExecutionRehearsal || !resultCaptureOwnerAcceptanceMaintenanceGate || !resultCaptureOwnerAcceptanceReadbackPreflightHold || !resultCaptureOwnerApprovedPreflightReleasePackage || !resultCaptureOwnerApprovedReleaseReadinessReadback || !resultCaptureOwnerReleaseApprovalGate || !resultCapturePostReleaseVerifierRollbackGate || !resultCaptureFinalReleaseCandidateReadback || !resultCaptureReleaseAuthorizationHold || !resultCaptureReleaseAuthorizationReadbackGate || !resultCaptureReleaseVerifierPreflightGate || !resultCaptureReleaseVerifierOwnerReviewPacket || !resultCaptureReleaseDecisionHold || !resultCaptureReleaseDecisionReadback || !resultCaptureReleaseDecisionNextHandoff || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { + if (error || !snapshot || !backlog || !backupTargets || !backupReadiness || !backupPolicy || !offsiteEscrow || !giteaHealth || !observabilityMatrix || !providerRouteMatrix || !deploymentLayout || !proactiveOperations || !interactionLearningProof || !liveReadModelGate || !redisDryRunGate || !learningWritebackPackage || !telegramReceiptPackage || !ownerApprovedLearningDryRun || !runtimeWriteGateReview || !postWriteVerifierPackage || !runtimeVerifierEvidenceReview || !reportAutomationReview || !reportStatusBoard || !reportRuntimeReadiness || !reportRuntimeDryRun || !reportRuntimeFixtureReadback || !runtimeWorkerShadowGate || !operationPermissionModel || !candidateOperationDryRunEvidence || !taskResultAuditTrail || !matchedPlaybookLearningGap || !criticReviewerResultCapture || !ownerApprovedResultCaptureDryRun || !ownerApprovedResultCaptureReadback || !runtimeReadbackApprovalPackage || !runtimeReadbackImplementationReview || !reportLiveDeliveryApprovalPackage || !runtimeReadbackFixtureApproval || !runtimeReadbackPromotionGate || !ownerApprovedFixturePromotionGate || !canonicalRuntimeReadbackOwnerAcceptance || !failureReceiptNoSendReplay || !reviewerQueueNoWriteReadback || !resultCaptureNoWriteReadback || !resultCapturePromotionApprovalGate || !ownerApprovedResultCapturePromotionDryRun || !resultCaptureWriteGateReview || !resultCaptureWriterImplementationReview || !resultCaptureWriterDryRunFixture || !resultCaptureWriterDryRunReadback || !resultCaptureOwnerPromotionReview || !resultCaptureOwnerApprovedExecutionRehearsal || !resultCaptureOwnerAcceptanceMaintenanceGate || !resultCaptureOwnerAcceptanceReadbackPreflightHold || !resultCaptureOwnerApprovedPreflightReleasePackage || !resultCaptureOwnerApprovedReleaseReadinessReadback || !resultCaptureOwnerReleaseApprovalGate || !resultCapturePostReleaseVerifierRollbackGate || !resultCaptureFinalReleaseCandidateReadback || !resultCaptureReleaseAuthorizationHold || !resultCaptureReleaseAuthorizationReadbackGate || !resultCaptureReleaseVerifierPreflightGate || !resultCaptureReleaseVerifierOwnerReviewPacket || !resultCaptureReleaseDecisionHold || !resultCaptureReleaseDecisionReadback || !resultCaptureReleaseDecisionNextHandoff || !resultCaptureReleaseDecisionInputPrep || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { return (
@@ -3436,6 +3442,27 @@ export function AutomationInventoryTab() { + resultCaptureReleaseDecisionNextHandoff.rollups.playbook_trust_write_count + resultCaptureReleaseDecisionNextHandoff.rollups.production_write_count ) + const resultCaptureReleaseDecisionInputPrepOverall = resultCaptureReleaseDecisionInputPrep.program_status.overall_completion_percent + const resultCaptureReleaseDecisionInputPackets = resultCaptureReleaseDecisionInputPrep.rollups.decision_input_packet_count + const resultCaptureReleaseDecisionMissingFields = resultCaptureReleaseDecisionInputPrep.rollups.missing_input_field_count + const resultCaptureReleaseDecisionInputBlockers = resultCaptureReleaseDecisionInputPrep.rollups.blocked_input_transition_count + const resultCaptureReleaseDecisionInputActions = resultCaptureReleaseDecisionInputPrep.rollups.operator_action_count + const resultCaptureReleaseDecisionInputApprovalRequired = resultCaptureReleaseDecisionInputPrep.rollups.approval_required_subtotal + const resultCaptureReleaseDecisionInputBlocked = resultCaptureReleaseDecisionInputPrep.rollups.blocked_and_critical_subtotal + const resultCaptureReleaseDecisionInputLiveWrites = ( + resultCaptureReleaseDecisionInputPrep.rollups.writer_apply_count + + resultCaptureReleaseDecisionInputPrep.rollups.execution_apply_count + + resultCaptureReleaseDecisionInputPrep.rollups.receipt_write_count + + resultCaptureReleaseDecisionInputPrep.rollups.reviewer_queue_write_count + + resultCaptureReleaseDecisionInputPrep.rollups.gateway_queue_write_count + + resultCaptureReleaseDecisionInputPrep.rollups.telegram_send_count + + resultCaptureReleaseDecisionInputPrep.rollups.bot_api_call_count + + resultCaptureReleaseDecisionInputPrep.rollups.report_receipt_write_count + + resultCaptureReleaseDecisionInputPrep.rollups.result_capture_write_count + + resultCaptureReleaseDecisionInputPrep.rollups.learning_write_count + + resultCaptureReleaseDecisionInputPrep.rollups.playbook_trust_write_count + + resultCaptureReleaseDecisionInputPrep.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 @@ -7996,6 +8023,125 @@ export function AutomationInventoryTab() {
+
+
+
+ + + {t('resultCaptureReleaseDecisionInputPrep.title')} + +
+ +
+ +
+ } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> +
+ +
+
+ {t('resultCaptureReleaseDecisionInputPrep.priorTitle')} +

+ {resultCaptureReleaseDecisionInputPrep.prior_next_handoff.readiness_note} +

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

+ {resultCaptureReleaseDecisionInputPrep.decision_input_truth.truth_note} +

+
+ + + + + + +
+
+
+ + {t('resultCaptureReleaseDecisionInputPrep.packetTitle')} +
+ {resultCaptureReleaseDecisionInputPrep.decision_input_packets.slice(0, 5).map(packet => ( +
+
+ + {packet.display_name} + + +
+ + {packet.input_summary} + +
+ + + + +
+
+ ))} +
+ +
+ {resultCaptureReleaseDecisionInputPrep.blocked_input_transitions.slice(0, 6).map(transition => ( +
+ {t('resultCaptureReleaseDecisionInputPrep.blockerTitle')} + + {transition.transition_id} + + + {transition.reason} + + +
+ ))} +
+ + {t('resultCaptureReleaseDecisionInputPrep.actionTitle')} +
+ {resultCaptureReleaseDecisionInputPrep.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 64d3bfc8a..43dfc722c 100644 --- a/apps/web/src/lib/api-client.ts +++ b/apps/web/src/lib/api-client.ts @@ -609,6 +609,11 @@ export const apiClient = { return handleResponse(res) }, + async getAiAgentResultCaptureReleaseDecisionInputPrep() { + const res = await fetch(`${API_BASE_URL}/agents/agent-result-capture-release-decision-input-prep`) + return handleResponse(res) + }, + async getAiAgentOwnerApprovedFixtureDryRun() { const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`) return handleResponse(res) @@ -9694,6 +9699,109 @@ export interface AiAgentResultCaptureReleaseDecisionNextHandoffSnapshot { } } +interface AiAgentReleaseDecisionInputPacket { + packet_id: string + display_name: string + owner_agent: string + source_handoff_id: string + current_task_id: string + target_next_task_id: string + input_status: string + required_input_type: string + input_summary: string + missing_fields: string[] + approval_required: boolean + runtime_write_allowed: boolean + telegram_send_allowed: boolean + evidence_hash?: string +} + +export interface AiAgentResultCaptureReleaseDecisionInputPrepSnapshot { + schema_version: 'ai_agent_result_capture_release_decision_input_prep_v1' + generated_at: string + program_status: { + overall_completion_percent: number + current_priority: 'P0' | 'P1' | 'P2' | 'P3' + current_task_id: 'P2-141' + next_task_id: 'P2-142' + read_only_mode: true + runtime_authority: 'result_capture_release_decision_input_prep_only_no_live_write' + status_note: string + } + source_refs: string[] + prior_next_handoff: AiAgentReleaseDecisionNextHandoffZeroCounts & { + schema_version: string + current_task_id: string + next_task_id: string + next_gate_handoff_count: number + stale_operator_action_count: number + blocked_handoff_transition_count: number + operator_action_count: number + approval_required_subtotal: number + blocked_and_critical_subtotal: number + readiness_note: string + } + decision_input_truth: AiAgentReleaseDecisionNextHandoffZeroCounts & { + p2_140_next_handoff_loaded: boolean + next_task_id_alignment_checked: boolean + stale_self_loop_containment_inherited: boolean + p2_141_input_prep_only: boolean + owner_input_packet_required: boolean + verifier_input_packet_required: boolean + rollback_input_packet_required: boolean + maintenance_window_input_required: boolean + live_apply_input_required: boolean + redaction_review_required: boolean + truth_note: string + owner_release_authorized: boolean + release_decision_passed: boolean + 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 + } + decision_input_packets: AiAgentReleaseDecisionInputPacket[] + blocked_input_transitions: { + transition_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 & { + decision_input_packet_count: number + owner_input_packet_count: number + verifier_input_packet_count: number + rollback_input_packet_count: number + maintenance_window_input_count: number + live_apply_input_count: number + missing_input_field_count: number + blocked_input_transition_count: number + operator_action_count: number + approval_required_subtotal: number + blocked_and_critical_subtotal: number + stale_operator_action_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 2d2e7ad11..bc0a7b472 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,36 @@ +## 2026-06-14|P2-141 釋出決策輸入準備包本地完成 + +**背景**:P2-140 release decision next handoff 已正式驗證並固定真正下一步為 `P2-141`;P2-141 因此只把 P2-140 的 next handoff 轉成 owner / verifier 決策輸入準備包,不接受口頭批准、不核發 release authorization、不寫 reviewer / Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 result capture、learning、PlayBook trust 或 production target。 + +**完成項目**: +- 新增 `ai_agent_result_capture_release_decision_input_prep_v1` schema、snapshot、service guard、API endpoint `GET /api/v1/agents/agent-result-capture-release-decision-input-prep`、API/service tests、治理頁 P2-141 區塊與繁中 UI 文案。 +- P2-141 snapshot 固定 5 個 decision input packet、15 個 missing input field、6 個 blocked input transition、5 個 operator action、仍需批准 `12`、阻擋總數 `12`、舊 action 隔離承接 `1`、正式寫入 / 發送 `0`。 +- 決策輸入準備包涵蓋 owner release、verifier、rollback owner、maintenance window、live apply;每包都只列缺欄位與 redacted evidence hash,不代表批准或授權。 +- Governance automation inventory 頁新增 P2-141 卡片,顯示準備包、缺欄位、阻擋轉換、操作事項、Gateway / Telegram / production write 全部 `0`。 + +**本地驗證**: +- JSON parse:P2-141 snapshot / schema、`zh-TW.json`、`en.json` 通過。 +- Python 編譯:P2-141 loader 與 `agents.py` 通過。 +- API/service pytest:P2-141 與 P2-140 regression `14 passed`。 +- i18n key / placeholder mirror:`keys_zh=11864`、`keys_en=11864`、missing `0 / 0`、placeholder diff `0`。 +- `source-control-owner-response-guard.py`:`SOURCE_CONTROL_OWNER_RESPONSE_GUARD_OK`。 +- `security-mirror-progress-guard.py`:`SECURITY_MIRROR_PROGRESS_GUARD_OK`。 +- `doc-secrets-sanity-check.py docs .gitea`:`DOC_SECRET_SANITY_OK scanned_files=802`。 +- `git diff --check` 通過。 +- `pnpm --filter @awoooi/web typecheck` 本臨時 worktree 因無 `node_modules` 回 `tsc: command not found`,需由 Gitea CD 乾淨環境驗證。 + +**安全邊界**: +- P2-141 仍是只讀 input prep;不得把準備包可見解讀成 owner release authorized、owner release approved、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、rollback owner confirmed、release decision passed、release authorization granted / 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。 +- 本段尚未正式部署;需要 feature commit、deploy marker、production API readback 與 desktop / mobile Browser smoke 後,才可記錄正式驗證完成。 + +**完成度**: +- P2-141 local slice:`100%`。 +- P2-141 production verification:`0%`。 +- active runtime gate、Telegram 實發、reviewer / Gateway queue write、production write 仍維持 `0`。 + +**下一步**: +- 推送 P2-141 feature commit,等待 Gitea CD / code-review;正式驗證通過後,才可由 `P2-142` 承接下一個只讀關卡。 + ## 2026-06-14|P2-140 釋出決策下一關交接讀回正式驗證完成 **背景**:P2-140 release decision next handoff 已由 feature commit `2fe31c91` 推進,CD deploy marker `40741425 chore(cd): deploy 2fe31c9 [skip ci]` 生效;後續前端遮罩修正 deploy markers `0ae1a25d chore(cd): deploy d8888e2 [skip ci]` 與 `a6b2d187 chore(cd): deploy cc67835 [skip ci]` 也已重驗 P2-140 正式站。正式站需要確認 API 與 governance UI 都讀到同一份只讀 handoff readback,且仍沒有 reviewer queue / Gateway / Telegram / Bot API / result capture / learning / production write。 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 a88316289..b219ea855 100644 --- a/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md +++ b/docs/ai/AI_AGENT_AUTOMATION_WORKLIST_2026-06-04.md @@ -12,7 +12,7 @@ | Nemotron 實際整合應用 | 30% | 完整回放前仍被關卡擋下 | `blocked_needs_evidence`,下一關是 `refresh_source_evidence_then_5_record_smoke_only` | | 工具 / 服務 / 套件 AI 自動化 | 92% | P0 已完成;P1 服務 / runtime / 監控 / provider / service health / 備份 / DR / 套件與供應鏈只讀基線已完成;P1-007 失敗限定通知合約與前端 redaction 合約已完成;下一主線是 P2-004 依賴 / 供應鏈漂移監控 | 狀態分類、盤點 schema、權限矩陣、靜態盤點種子、只讀 API、UI 骨架、驗證、自動化待辦 schema / 快照 / API / 分組 UI、Backup / DR 目標盤點、準備度矩陣、備份通知政策、Backup / DR 證據 UI、復原演練批准包模板、異地 / escrow 準備度狀態、任務批准邊界、確定性進度彙總、Python 套件 / 供應鏈只讀基線、JS pnpm/npm 只讀基線、Docker build surface 只讀基線、CVE / license / drift 嚴重度政策、定期依賴漂移與外部資料來源檢查設計、依賴升級批准包模板、runtime_surface_inventory_v1 schema / snapshot / API / UI、gitea_workflow_runner_health_v1 schema / snapshot / API / UI、observability_contract_matrix_v1 schema / snapshot / API / UI、ai_provider_route_matrix_v1 schema / snapshot / API / UI、service_health_gap_matrix_v1 schema / snapshot / API / UI、service health evidence cards UI、service_health_failure_notification_policy_v1 schema / snapshot / API / UI 已完成 | | OpenClaw / Hermes / NemoTron 佈建布局 | 45% | P1-401 / P1-402 已完成;仍是只讀 layout 與治理頁顯示,不是 runtime deploy | `ai_agent_deployment_layout_v1` schema、`ai_agent_deployment_layout_2026-06-11.json`、`GET /api/v1/agents/agent-deployment-layout`、治理頁自動化盤點 UI、`AI_AGENT_DEPLOYMENT_LAYOUT_2026-06-11.md` | -| OpenClaw / Hermes / NemoTron 主動溝通、學習與成長證據 | 100% | P2-401A 到 P2-140 已完成只讀證據面、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;P2-140 已正式驗證,固定 5 個 next-gate handoff、1 個 stale operator action containment、6 個 blocked handoff transition 與 5 個 operator action,並隔離 P2-139 自我迴圈;後續 deploy markers `0ae1a25d` 與 `a6b2d187` 也已完成 P2-140 recheck。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_next_handoff_v1`、`GET /api/v1/agents/agent-result-capture-release-decision-next-handoff`、feature commit `2fe31c91`、deploy marker `40741425`、最新 recheck deploy marker `a6b2d187`、P2-140 正式 API readback、desktop / mobile smoke、P2-140 + P2-139 regression `14 passed`、JSON parse、Python compile、i18n key mirror `11837`、治理頁 P2-140 區塊、禁用內部協作片語 `0`、水平溢位 `0`、內容區危險控制 `0`、console error `0`、HTTP 4xx/5xx `0`;MASTER §3.2.1b / §3.2.1d / §3.4.3 | +| OpenClaw / Hermes / NemoTron 主動溝通、學習與成長證據 | 100% | P2-401A 到 P2-141 已完成只讀證據面、runtime / report / result-capture gates、no-write readback、promotion review、writer implementation review、writer dry-run fixture、writer dry-run readback、owner promotion execution gate、owner-approved execution rehearsal、owner acceptance / maintenance window gate、owner acceptance readback / preflight hold、owner-approved preflight release package、owner-approved release readiness readback、owner release approval gate、post-release verifier / rollback gate、final release candidate readback、release authorization hold / readback gate、release verifier preflight / owner review packet、release decision hold / readback、release decision next handoff 與 release decision input prep;P2-141 已本地完成,固定 5 個 decision input packet、15 個 missing input field、6 個 blocked input transition 與 5 個 operator action,並把 P2-140 下一關交接轉成 owner / verifier / rollback / maintenance / live-apply 五類決策輸入準備包。runtime worker、DB migration、production Redis consumer group、canonical runtime readback、live query、runtime score、result capture write、Telegram 實發、delivery receipt E2E、live report delivery、reviewer queue write、Gateway queue write、AI analysis runtime、中低風險 auto worker、KM / LOGBOOK / audit DB / timeline / PlayBook trust 寫入、SDK / 付費服務仍未開 gate | `ai_agent_result_capture_release_decision_input_prep_v1`、`GET /api/v1/agents/agent-result-capture-release-decision-input-prep`、P2-141 本地 API/service regression `14 passed`、JSON parse、Python compile、i18n key mirror `11864`、guard 與 doc secret sanity 通過、治理頁 P2-141 區塊;P2-140 正式 feature commit `2fe31c91`、deploy marker `40741425`、最新 recheck deploy marker `a6b2d187`;MASTER §3.2.1b / §3.2.1d / §3.4.3 | | AI Agent 主動營運委派與版本生命週期 | 100% | P2-402A / P2-402B / P2-402C / P2-402D / P2-402E / P2-402F / P2-402G 已完成;已建立 repo-only 版本新鮮度快照、工具採用批准包、Telegram action-required digest policy、Gitea PR 草案 lane、host / K3s / stateful 版本只讀盤點、API 與 governance UI。定期排程、外部版本查詢、工具安裝、CI 變更、套件升級、主機更新、container pull、實際 PR creation、auto merge、Telegram 實發、SSH、kubectl、重啟仍未開 gate | `ai_agent_proactive_operations_contract_v1`、`ai_agent_version_freshness_snapshot_v1`、`ai_agent_tool_adoption_approval_package_v1`、`ai_agent_telegram_action_required_digest_policy_v1`、`ai_agent_gitea_pr_draft_lane_v1`、`ai_agent_host_stateful_version_inventory_v1`、`GET /api/v1/agents/agent-proactive-operations-contract`、`GET /api/v1/agents/agent-version-freshness-snapshot`、`GET /api/v1/agents/agent-tool-adoption-approval-package`、`GET /api/v1/agents/agent-telegram-action-required-digest-policy`、`GET /api/v1/agents/agent-gitea-pr-draft-lane`、`GET /api/v1/agents/agent-host-stateful-version-inventory`、`/zh-TW/governance?tab=automation-inventory`、MASTER §3.2.1c | | 本工作清單與分析報告 | 100% | 已完成 | 本 MD 文件 | @@ -122,13 +122,22 @@ - 後續前端遮罩 deploy markers `0ae1a25d` 與 `a6b2d187` 生效後已補跑 P2-140 production recheck;desktop / mobile 均維持必要文案可見、水平溢位 `0`、overflowing element `0`、內容區危險控制 `0`、console error `0`、HTTP 4xx/5xx `0`。 - P2-140 已可由 `P2-141` 承接;仍不得直接開啟 result capture writer、learning writer、PlayBook trust writer、reviewer queue write、Gateway queue write、Telegram send、Bot API call 或 production write。 +### 2026-06-14 13:08 狀態同步 + +- `P2-141` release decision input prep 已本地完成:新增 `ai_agent_result_capture_release_decision_input_prep_v1`、`GET /api/v1/agents/agent-result-capture-release-decision-input-prep`、治理頁 P2-141 區塊與繁中 UI 文案。 +- P2-141 承接 P2-140 next handoff,把下一關交接整理成 owner release、verifier、rollback owner、maintenance window、live apply 五類 decision input packet,供後續 owner / verifier 審查,而不是寫入任何正式佇列。 +- P2-141 固定 5 個 decision input packet、15 個 missing input field、6 個 blocked input transition、5 個 operator action、需批准 `12`、阻擋 `12`、正式寫入 / 發送 `0`。 +- 本地證據:P2-141 + P2-140 API/service regression `14 passed`、JSON parse、Python compile、i18n key mirror `11864`、guard 與 doc secret sanity 通過;本臨時 worktree 無 `node_modules`,Web typecheck 需由 Gitea CD 乾淨環境驗證。 +- 邊界仍維持: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 write、Gateway queue write、Telegram send、Bot API、report receipt、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 全部 `0 / false`。 +- P2-141 推送與正式驗證後才可交給 `P2-142`;仍不得直接開啟 result capture writer、learning writer、PlayBook trust writer、reviewer queue write、Gateway queue write、Telegram send、Bot API call 或 production write。 + AI Agent 自動化工作包目前完成度:**99.8%**。本工作清單文件本身完成度:**100%**。 三 Agent 佈建布局目前完成度:**45%**。第一波已完成只讀 schema / snapshot / API / 測試 / 報告,第二波已接入治理頁自動化盤點 UI;正式 runtime 佈署、Telegram E2E 發送與 AgentSession 工作流仍需逐項 gate。 -三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。P2-403A 到 P2-140 已把互動證據、報表治理、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 固定成可驗證證據。P2-140 已由 feature commit `2fe31c91` 與 deploy marker `40741425` 正式驗證,並在後續遮罩 deploy markers `0ae1a25d` 與 `a6b2d187` 後完成 production recheck;P2-139 已由 feature commit `d41b1a38` 與 deploy marker `df867bd6` 正式驗證;P2-138 最新寫入邊界補強也已正式驗證,deploy marker `923fb117`。目前 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-141`,仍只能接續只讀關卡,不得開啟 runtime writer、Gateway queue、Telegram send、Bot API 或 production write。 +三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。P2-403A 到 P2-141 已把互動證據、報表治理、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 固定成可驗證證據。P2-141 已本地完成,正式驗證後才可進入 P2-142;P2-140 已由 feature commit `2fe31c91` 與 deploy marker `40741425` 正式驗證,並在後續遮罩 deploy markers `0ae1a25d` 與 `a6b2d187` 後完成 production recheck;P2-139 已由 feature commit `d41b1a38` 與 deploy marker `df867bd6` 正式驗證。目前 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-141 正式部署驗證,再由 `P2-142` 承接只讀關卡;不得開啟 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-140` 已補互動、學習證據面、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。下一步是 P2-141;外部 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-141` 已補互動、學習證據面、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。下一步是 P2-141 正式驗證後進 P2-142;外部 registry / package source / host probe / SSH / kubectl / 工具安裝 / CI 變更 / 實際 PR creation / Telegram 實發與 learning write 仍需 gate。 完成度計算模型: @@ -1119,6 +1128,7 @@ UI: | P2-138 | 完成 | 100 | OpenClaw + Hermes + NemoTron | release decision hold | `ai_agent_result_capture_release_decision_hold_v1` / schema / snapshot / 只讀 API / governance UI;feature commit `655df33d` 與 maintenance window 補強 commit `1ae67f1f` 已由 deploy marker `bfd26e76` 正式驗證;承接 P2-137,只建立 5 個 release decision hold、5 個 owner decision hold、5 個 verifier decision hold、5 個 rollback decision hold、5 個 maintenance window decision hold、5 個 live-apply decision hold、6 個 blocked decision transition、5 個 operator action;需批准 `12`、阻擋 `12`;runtime authority 固定 `result_capture_release_decision_hold_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-138 + P2-137 pytest `15 passed`、JSON parse、Python compile、i18n key mirror `11777`、Web typecheck 與 Web production build 通過;production API readback、desktop / mobile smoke、水平溢位 `0`、P2-138 卡片危險控制 `0`、console / page error `0`、HTTP 4xx/5xx `0`;不得把 P2-138 當 runtime gate,已由 P2-139 承接 | | P2-139 | 完成 | 100 | OpenClaw + Hermes + NemoTron | release decision readback | `ai_agent_result_capture_release_decision_readback_v1` / schema / snapshot / 只讀 API / governance UI;feature commit `d41b1a38`、deploy marker `df867bd6` 已正式驗證;承接 P2-138,只讀回 5 個 release decision readback、5 個 owner decision readback、5 個 verifier decision readback、5 個 rollback decision readback、5 個 maintenance window decision readback、5 個 live-apply decision readback、6 個 blocked readback transition、5 個 operator action;需批准 `12`、阻擋 `12`;runtime authority 固定 `result_capture_release_decision_readback_only_no_live_write`;owner release authorized / owner review approved / owner decision approved / verifier decision approved / maintenance window approved / release decision passed / release authorization granted / passed / rollback release / live apply release / writer apply / execution apply / receipt write / reviewer queue / Gateway / Telegram / Bot API / result capture / learning / PlayBook trust / production write / secret read / destructive operation 全為 `0` | 本地 P2-139 API/service pytest `7 passed`、JSON parse、Python compile、i18n key mirror `11809` 通過;production API readback、desktop / mobile smoke、水平溢位 `0`、P2-139 卡片危險控制 `0`、console error `0`、HTTP 4xx/5xx `0`;不得把 P2-139 當 runtime gate,已可由 P2-140 承接 | | P2-140 | 完成 | 100 | OpenClaw + Hermes + NemoTron | release decision next handoff readback | `ai_agent_result_capture_release_decision_next_handoff_v1` / schema / snapshot / 只讀 API / governance UI;feature commit `2fe31c91`、deploy marker `40741425` 已正式驗證,後續 deploy markers `0ae1a25d` 與 `a6b2d187` 已重驗;承接 P2-139,只讀回下一關交接並隔離 P2-139 自我迴圈;固定 5 個 next-gate handoff、1 個 stale operator action containment、6 個 blocked handoff transition、5 個 operator action;需批准 `12`、阻擋 `12`;runtime authority 固定 `result_capture_release_decision_next_handoff_only_no_live_write`;owner release authorized / owner review approved / owner decision approved / verifier decision approved / maintenance window approved / release decision passed / release authorization granted / passed / rollback release / live apply release / writer apply / execution apply / receipt write / reviewer queue / Gateway / Telegram / Bot API / result capture / learning / PlayBook trust / production write / secret read / destructive operation 全為 `0` | 本地 P2-140 + P2-139 API/service regression `14 passed`、JSON parse、Python compile、i18n key mirror `11837`、guard 與 doc secret sanity 通過;production API readback、desktop / mobile smoke、in-app browser smoke、水平溢位 `0`、內容區危險控制 `0`、console error `0`、HTTP 4xx/5xx `0`;不得把 P2-140 當 runtime gate,已可由 P2-141 承接 | +| P2-141 | 本地完成 | 100 | OpenClaw + Hermes + NemoTron | release decision input prep | `ai_agent_result_capture_release_decision_input_prep_v1` / schema / snapshot / 只讀 API / governance UI;承接 P2-140 next handoff,整理 5 個 decision input packet、15 個 missing input field、6 個 blocked input transition、5 個 operator action;需批准 `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 + P2-140 API/service regression `14 passed`、JSON parse、Python compile、i18n key mirror `11864`、guard 與 doc secret sanity 通過;正式部署與 production desktop / mobile smoke 待 Gitea CD 完成後補驗,不得把 input prep 當 runtime gate,正式驗證後才可由 P2-142 承接 | ### P3 - 候選 Agent 擴展 diff --git a/docs/evaluations/ai_agent_result_capture_release_decision_input_prep_2026-06-14.json b/docs/evaluations/ai_agent_result_capture_release_decision_input_prep_2026-06-14.json new file mode 100644 index 000000000..11e9d2c6f --- /dev/null +++ b/docs/evaluations/ai_agent_result_capture_release_decision_input_prep_2026-06-14.json @@ -0,0 +1,339 @@ +{ + "schema_version": "ai_agent_result_capture_release_decision_input_prep_v1", + "generated_at": "2026-06-14T13:08:00+08:00", + "program_status": { + "overall_completion_percent": 100, + "current_priority": "P2", + "current_task_id": "P2-141", + "next_task_id": "P2-142", + "read_only_mode": true, + "runtime_authority": "result_capture_release_decision_input_prep_only_no_live_write", + "status_note": "P2-141 只把 P2-140 next handoff 轉成 owner / verifier 決策輸入準備包;不得把準備包解讀成批准、不得寫 reviewer / Gateway queue、不得送 Telegram、不得呼叫 Bot API、不得寫 result capture、learning、PlayBook trust 或 production target。" + }, + "source_refs": [ + "docs/evaluations/ai_agent_result_capture_release_decision_next_handoff_2026-06-14.json", + "docs/evaluations/ai_agent_result_capture_release_decision_readback_2026-06-14.json", + "docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md#61-建立-release-decision-next-handoff-readback" + ], + "prior_next_handoff": { + "schema_version": "ai_agent_result_capture_release_decision_next_handoff_v1", + "current_task_id": "P2-140", + "next_task_id": "P2-141", + "next_gate_handoff_count": 5, + "stale_operator_action_count": 1, + "blocked_handoff_transition_count": 6, + "operator_action_count": 5, + "approval_required_subtotal": 12, + "blocked_and_critical_subtotal": 12, + "readiness_note": "P2-140 已確認 P2-139 自我迴圈被隔離,下一步只能進入 P2-141 決策輸入準備,不得回頭重跑 P2-139 或 P2-140。", + "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 + }, + "decision_input_truth": { + "p2_140_next_handoff_loaded": true, + "next_task_id_alignment_checked": true, + "stale_self_loop_containment_inherited": true, + "p2_141_input_prep_only": true, + "owner_input_packet_required": true, + "verifier_input_packet_required": true, + "rollback_input_packet_required": true, + "maintenance_window_input_required": true, + "live_apply_input_required": true, + "redaction_review_required": true, + "truth_note": "P2-141 只準備 owner / verifier 決策需要的可審核輸入;所有批准、釋出、回滾、正式套用、寫入、發送與套用仍保持關閉。", + "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_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 + }, + "decision_input_packets": [ + { + "packet_id": "decision_input_owner_release", + "display_name": "Owner release 決策輸入", + "owner_agent": "openclaw", + "source_handoff_id": "next_gate_handoff_result_capture", + "current_task_id": "P2-141", + "target_next_task_id": "P2-142", + "input_status": "missing_required_decision_input", + "required_input_type": "owner_release_decision", + "input_summary": "需要 owner 明確決策、理由與可審核 evidence refs;此包只整理輸入,不代表 release 已被批准。", + "missing_fields": ["owner_decision", "decision_reason", "redacted_evidence_refs"], + "approval_required": true, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:2a01a0b8df7a4ec38e4b5dcedb233a81aa1a6be6d56bff7b28c53d2d92f30411" + }, + { + "packet_id": "decision_input_verifier", + "display_name": "Verifier 決策輸入", + "owner_agent": "openclaw", + "source_handoff_id": "next_gate_handoff_reviewer_queue", + "current_task_id": "P2-141", + "target_next_task_id": "P2-142", + "input_status": "missing_required_decision_input", + "required_input_type": "post_release_verifier_decision", + "input_summary": "需要 verifier scope、驗證準則與失敗升級條件;此包不啟動 verifier runtime。", + "missing_fields": ["verifier_scope", "verification_criteria", "failure_escalation"], + "approval_required": true, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:1bd9c2733e2364617d1d6d83f7fbdd4f4aa8f0d4fd71ae03f557ff5574dbda72" + }, + { + "packet_id": "decision_input_rollback_owner", + "display_name": "Rollback owner 決策輸入", + "owner_agent": "hermes", + "source_handoff_id": "next_gate_handoff_playbook_trust", + "current_task_id": "P2-141", + "target_next_task_id": "P2-142", + "input_status": "missing_required_decision_input", + "required_input_type": "rollback_owner_decision", + "input_summary": "需要 rollback owner、回滾條件與回滾驗證計畫;此包不確認 rollback owner。", + "missing_fields": ["rollback_owner", "rollback_condition", "rollback_validation_plan"], + "approval_required": true, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:ad394acff54dd8a42f8c3cdd9bd9f33d7ca05667731097d8cebd5420f31d2c7b" + }, + { + "packet_id": "decision_input_maintenance_window", + "display_name": "維護窗口決策輸入", + "owner_agent": "openclaw", + "source_handoff_id": "next_gate_handoff_gateway_queue", + "current_task_id": "P2-141", + "target_next_task_id": "P2-142", + "input_status": "missing_required_decision_input", + "required_input_type": "maintenance_window_decision", + "input_summary": "需要維護時間、影響範圍與通知計畫;此包不批准維護窗口。", + "missing_fields": ["maintenance_window", "impact_scope", "notification_plan"], + "approval_required": true, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:8d6057e03cf8ed58106893f08da44d0bb8875538dd09594459a307ea9cc7fa46" + }, + { + "packet_id": "decision_input_live_apply", + "display_name": "正式套用決策輸入", + "owner_agent": "openclaw", + "source_handoff_id": "next_gate_handoff_learning", + "current_task_id": "P2-141", + "target_next_task_id": "P2-142", + "input_status": "missing_required_decision_input", + "required_input_type": "live_apply_decision", + "input_summary": "需要正式套用策略、停止條件與驗收證據;此包不釋放 writer 或 execution apply。", + "missing_fields": ["live_apply_strategy", "stop_condition", "acceptance_evidence"], + "approval_required": true, + "runtime_write_allowed": false, + "telegram_send_allowed": false, + "evidence_hash": "sha256:633f03e31bd8277b2963d357c0bf96331698e4180c71e7233d526eb2157a633d" + } + ], + "blocked_input_transitions": [ + { + "transition_id": "blocked_owner_release_without_decision", + "status": "blocked_by_missing_input", + "reason": "owner release decision 尚未提供,不能把準備包轉成批准。", + "runtime_write_allowed": false + }, + { + "transition_id": "blocked_verifier_without_criteria", + "status": "blocked_by_missing_input", + "reason": "verifier 準則與升級條件尚未提供,不能啟動驗證器。", + "runtime_write_allowed": false + }, + { + "transition_id": "blocked_rollback_without_owner", + "status": "blocked_by_missing_input", + "reason": "rollback owner 與回滾驗證計畫尚未提供,不能確認回滾。", + "runtime_write_allowed": false + }, + { + "transition_id": "blocked_maintenance_window_without_notice", + "status": "blocked_by_missing_input", + "reason": "維護窗口與通知計畫尚未提供,不能批准維護窗口。", + "runtime_write_allowed": false + }, + { + "transition_id": "blocked_live_apply_without_acceptance", + "status": "blocked_by_missing_input", + "reason": "正式套用策略、停止條件與驗收證據尚未提供,不能釋放 writer。", + "runtime_write_allowed": false + }, + { + "transition_id": "blocked_gateway_queue_without_owner_packet", + "status": "blocked_by_policy", + "reason": "owner / verifier 決策輸入尚未完整,不得寫 reviewer queue 或 Gateway queue。", + "runtime_write_allowed": false + } + ], + "operator_actions": [ + { + "action_id": "prepare_owner_decision_input_packet", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "整理 owner 決策、理由與 redacted evidence refs;不得把本步驟當成 owner 已批准。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_verifier_decision_input_packet", + "owner_agent": "openclaw", + "status": "ready_for_operator_review", + "operator_instruction": "整理 verifier scope、驗證準則與失敗升級條件;不得啟動 verifier runtime。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_rollback_owner_input_packet", + "owner_agent": "hermes", + "status": "ready_for_operator_review", + "operator_instruction": "整理 rollback owner、回滾條件與回滾驗證計畫;不得確認 rollback owner。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_maintenance_window_input_packet", + "owner_agent": "openclaw", + "status": "approval_required", + "operator_instruction": "整理維護窗口、影響範圍與通知計畫;不得批准維護窗口或送出通知。", + "runtime_write_allowed": false + }, + { + "action_id": "prepare_live_apply_input_packet", + "owner_agent": "openclaw", + "status": "approval_required", + "operator_instruction": "整理正式套用策略、停止條件與驗收證據;不得釋放 writer 或 execution apply。", + "runtime_write_allowed": false + } + ], + "display_redaction_contract": { + "redaction_required": true, + "raw_prompt_display_allowed": false, + "private_reasoning_display_allowed": false, + "secret_value_display_allowed": false, + "raw_runtime_payload_display_allowed": false, + "internal_collaboration_content_display_allowed": false, + "frontend_display_policy": "前端只能顯示決策輸入摘要、缺欄位、只讀狀態與 redacted evidence hash;不得顯示內部協作內容、推理內容、token、secret 或原始 runtime payload。" + }, + "rollups": { + "decision_input_packet_count": 5, + "owner_input_packet_count": 1, + "verifier_input_packet_count": 1, + "rollback_input_packet_count": 1, + "maintenance_window_input_count": 1, + "live_apply_input_count": 1, + "missing_input_field_count": 15, + "blocked_input_transition_count": 6, + "operator_action_count": 5, + "approval_required_subtotal": 12, + "blocked_and_critical_subtotal": 12, + "stale_operator_action_count": 1, + "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/schemas/ai_agent_result_capture_release_decision_input_prep_v1.schema.json b/docs/schemas/ai_agent_result_capture_release_decision_input_prep_v1.schema.json new file mode 100644 index 000000000..134e908df --- /dev/null +++ b/docs/schemas/ai_agent_result_capture_release_decision_input_prep_v1.schema.json @@ -0,0 +1,286 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://awoooi.wooo.work/schemas/ai_agent_result_capture_release_decision_input_prep_v1.schema.json", + "title": "AI Agent Result Capture Release Decision Input Prep", + "type": "object", + "required": [ + "schema_version", + "generated_at", + "program_status", + "prior_next_handoff", + "decision_input_truth", + "decision_input_packets", + "blocked_input_transitions", + "operator_actions", + "display_redaction_contract", + "rollups" + ], + "properties": { + "schema_version": { + "const": "ai_agent_result_capture_release_decision_input_prep_v1" + }, + "generated_at": { + "type": "string" + }, + "program_status": { + "type": "object", + "required": [ + "overall_completion_percent", + "current_priority", + "current_task_id", + "next_task_id", + "read_only_mode", + "runtime_authority", + "status_note" + ], + "properties": { + "overall_completion_percent": { + "const": 100 + }, + "current_priority": { + "const": "P2" + }, + "current_task_id": { + "const": "P2-141" + }, + "next_task_id": { + "const": "P2-142" + }, + "read_only_mode": { + "const": true + }, + "runtime_authority": { + "const": "result_capture_release_decision_input_prep_only_no_live_write" + }, + "status_note": { + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": true + }, + "prior_next_handoff": { + "type": "object", + "required": [ + "schema_version", + "current_task_id", + "next_task_id", + "next_gate_handoff_count", + "stale_operator_action_count", + "blocked_handoff_transition_count", + "operator_action_count", + "readiness_note" + ], + "properties": { + "schema_version": { + "const": "ai_agent_result_capture_release_decision_next_handoff_v1" + }, + "current_task_id": { + "const": "P2-140" + }, + "next_task_id": { + "const": "P2-141" + }, + "next_gate_handoff_count": { + "const": 5 + }, + "stale_operator_action_count": { + "const": 1 + }, + "blocked_handoff_transition_count": { + "const": 6 + }, + "operator_action_count": { + "const": 5 + }, + "readiness_note": { + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": true + }, + "decision_input_truth": { + "type": "object", + "required": [ + "p2_140_next_handoff_loaded", + "next_task_id_alignment_checked", + "stale_self_loop_containment_inherited", + "p2_141_input_prep_only", + "owner_input_packet_required", + "verifier_input_packet_required", + "rollback_input_packet_required", + "maintenance_window_input_required", + "live_apply_input_required", + "redaction_review_required", + "truth_note" + ], + "properties": { + "p2_140_next_handoff_loaded": { + "const": true + }, + "next_task_id_alignment_checked": { + "const": true + }, + "stale_self_loop_containment_inherited": { + "const": true + }, + "p2_141_input_prep_only": { + "const": true + }, + "truth_note": { + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": true + }, + "decision_input_packets": { + "type": "array", + "minItems": 5, + "maxItems": 5, + "items": { + "type": "object", + "required": [ + "packet_id", + "display_name", + "owner_agent", + "source_handoff_id", + "current_task_id", + "target_next_task_id", + "input_status", + "required_input_type", + "input_summary", + "missing_fields", + "approval_required", + "runtime_write_allowed", + "telegram_send_allowed" + ], + "properties": { + "packet_id": { + "type": "string" + }, + "current_task_id": { + "const": "P2-141" + }, + "target_next_task_id": { + "const": "P2-142" + }, + "approval_required": { + "const": true + }, + "runtime_write_allowed": { + "const": false + }, + "telegram_send_allowed": { + "const": false + }, + "missing_fields": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + } + }, + "additionalProperties": true + } + }, + "blocked_input_transitions": { + "type": "array", + "minItems": 6, + "maxItems": 6 + }, + "operator_actions": { + "type": "array", + "minItems": 5, + "maxItems": 5 + }, + "display_redaction_contract": { + "type": "object", + "required": [ + "redaction_required", + "raw_prompt_display_allowed", + "private_reasoning_display_allowed", + "secret_value_display_allowed", + "raw_runtime_payload_display_allowed", + "internal_collaboration_content_display_allowed", + "frontend_display_policy" + ], + "properties": { + "redaction_required": { + "const": true + }, + "raw_prompt_display_allowed": { + "const": false + }, + "private_reasoning_display_allowed": { + "const": false + }, + "secret_value_display_allowed": { + "const": false + }, + "raw_runtime_payload_display_allowed": { + "const": false + }, + "internal_collaboration_content_display_allowed": { + "const": false + } + }, + "additionalProperties": true + }, + "rollups": { + "type": "object", + "required": [ + "decision_input_packet_count", + "missing_input_field_count", + "blocked_input_transition_count", + "operator_action_count", + "approval_required_subtotal", + "blocked_and_critical_subtotal", + "reviewer_queue_write_count", + "gateway_queue_write_count", + "telegram_send_count", + "bot_api_call_count", + "production_write_count" + ], + "properties": { + "decision_input_packet_count": { + "const": 5 + }, + "missing_input_field_count": { + "const": 15 + }, + "blocked_input_transition_count": { + "const": 6 + }, + "operator_action_count": { + "const": 5 + }, + "approval_required_subtotal": { + "const": 12 + }, + "blocked_and_critical_subtotal": { + "const": 12 + }, + "reviewer_queue_write_count": { + "const": 0 + }, + "gateway_queue_write_count": { + "const": 0 + }, + "telegram_send_count": { + "const": 0 + }, + "bot_api_call_count": { + "const": 0 + }, + "production_write_count": { + "const": 0 + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true +} 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 0c7357a08..ffb138046 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 @@ -678,6 +678,7 @@ Alert / Sentry / SigNoz / Gitea / Market Watch / Operator | `docs/evaluations/ai_agent_result_capture_release_decision_hold_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-decision-hold` | P2-138 release decision hold;承接 P2-137 release verifier owner review packet,建立 5 個 release decision hold、5 個 owner decision hold、5 個 verifier decision hold、5 個 rollback decision hold、5 個 maintenance window decision hold、5 個 live-apply decision hold、6 個 blocked decision transition 與 5 個 operator action;runtime authority 固定 `result_capture_release_decision_hold_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 `655df33d` 與 maintenance window 補強 commit `1ae67f1f` 已由 deploy marker `bfd26e76` 正式驗證,正式 API readback 與 desktop / mobile smoke 已完成,下一步 P2-139 release decision readback | | `docs/evaluations/ai_agent_result_capture_release_decision_readback_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-decision-readback` | P2-139 release decision readback;承接 P2-138 release decision hold,建立 5 個 release decision readback、5 個 owner decision readback、5 個 verifier decision readback、5 個 rollback decision readback、5 個 maintenance window decision readback、5 個 live-apply decision readback、6 個 blocked readback transition 與 5 個 operator action;runtime authority 固定 `result_capture_release_decision_readback_only_no_live_write`;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、canonical runtime target read、live query、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部 `0 / false`;feature commit `d41b1a38`、deploy marker `df867bd6`、正式 API readback、desktop / mobile smoke、禁用內部協作片語 `0`、水平溢位 `0`、危險控制 `0`、console error `0`、HTTP 4xx/5xx `0` 已完成,下一步 P2-140 | | `docs/evaluations/ai_agent_result_capture_release_decision_next_handoff_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-decision-next-handoff` | P2-140 release decision next handoff readback;承接 P2-139 release decision readback,建立 5 個 next-gate handoff、1 個 stale operator action containment、6 個 blocked handoff transition 與 5 個 operator action;runtime authority 固定 `result_capture_release_decision_next_handoff_only_no_live_write`;P2-139 的 `prepare_p2_139_release_decision_readback` 自我迴圈已標示為 `contained_read_only`,真正下一步為 P2-141;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、canonical runtime target read、live query、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read 與 destructive action 全部 `0 / false`;feature commit `2fe31c91`、deploy marker `40741425`、最新 recheck deploy marker `a6b2d187`、正式 API readback、desktop / mobile smoke、in-app browser smoke、禁用內部協作片語 `0`、水平溢位 `0`、內容區危險控制 `0`、console error `0`、HTTP 4xx/5xx `0` 已完成,下一步 P2-141 | +| `docs/evaluations/ai_agent_result_capture_release_decision_input_prep_2026-06-14.json` + `GET /api/v1/agents/agent-result-capture-release-decision-input-prep` | P2-141 release decision input prep;承接 P2-140 release decision next handoff,把下一關交接整理成 5 個 decision input packet、15 個 missing input field、6 個 blocked input transition 與 5 個 operator action;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`;本地 P2-141 + P2-140 API/service regression `14 passed`、JSON parse、Python compile、i18n key mirror、guard 與 doc secret sanity 已完成,正式驗證後才可由 P2-142 承接 | | `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 主動營運委派與版本生命週期契約 @@ -807,6 +808,7 @@ Repo / registry / release notes / K8s / host / observability / backup evidence 59. 建立 release decision hold。✅ P2-138 最新合約已完成並正式驗證;release decision hold `5`、owner decision hold `5`、verifier decision hold `5`、rollback decision hold `5`、maintenance window decision hold `5`、live-apply decision hold `5`、blocked decision transition `6`、operator action `5`,approval-required release / owner / verifier / rollback / maintenance / live apply `2 / 2 / 2 / 2 / 2 / 2`、blocked release / owner / verifier / rollback / maintenance / live apply `1 / 1 / 1 / 1 / 1 / 1`、critical blocker `6`;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 仍為 `0 / false`;本地 P2-138 + P2-137 regression `15 passed`、JSON parse、Python compile、i18n key mirror、Web typecheck 與 Web production build 通過;deploy marker `bfd26e76`、正式 API readback 與 desktop / mobile smoke 已完成。已由 P2-139 承接。 60. 建立 release decision readback。✅ P2-139 已完成並正式驗證;release decision readback `5`、owner decision readback `5`、verifier decision readback `5`、rollback decision readback `5`、maintenance window decision readback `5`、live-apply decision readback `5`、blocked readback transition `6`、operator action `5`,approval-required release / owner / verifier / rollback / maintenance / live apply `2 / 2 / 2 / 2 / 2 / 2`、blocked release / owner / verifier / rollback / maintenance / live apply `1 / 1 / 1 / 1 / 1 / 1`、critical blocker `6`;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 仍為 `0 / false`;本地 API/service pytest `7 passed`、JSON parse、Python compile、i18n key mirror 通過;deploy marker `df867bd6`、正式 API readback 與 desktop / mobile smoke 已完成。已可由 P2-140 承接。 61. 建立 release decision next handoff readback。✅ P2-140 已完成並正式驗證;next-gate handoff `5`、stale operator action containment `1`、blocked handoff transition `6`、operator action `5`、approval required subtotal `12`、blocked + critical subtotal `12`;P2-139 的 `prepare_p2_139_release_decision_readback` 自我迴圈已標示為 `contained_read_only`,真正下一步固定為 P2-141;owner release authorized、owner review approved、owner decision approved、verifier decision approved、maintenance window approved、release decision passed、release authorization granted、release authorization passed、rollback release passed、live apply release passed、writer apply、execution apply、receipt write、reviewer queue write、Gateway queue write、Telegram send、Bot API call、report receipt write、result capture write、learning write、PlayBook trust write、production write、secret read、destructive operation 仍為 `0 / false`;P2-140 + P2-139 regression `14 passed`、JSON parse、Python compile、i18n key mirror、guard 與 doc secret sanity 通過;deploy marker `40741425`、最新 recheck deploy marker `a6b2d187`、正式 API readback、in-app browser、desktop / mobile smoke 已完成。已可由 P2-141 承接。 +62. 建立 release decision input prep。✅ P2-141 已本地完成;decision input packet `5`、missing input field `15`、blocked input transition `6`、operator action `5`、approval required subtotal `12`、blocked + critical subtotal `12`;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 `14 passed`、JSON parse、Python compile、i18n key mirror、guard 與 doc secret sanity 通過;正式驗證後才可由 P2-142 承接。 #### 3.2.1d 2026-06-11 Agent 互動、學習與成長證據面 @@ -2003,6 +2005,14 @@ Phase 6 完成後 - 後續遮罩 deploy markers `0ae1a25d chore(cd): deploy d8888e2 [skip ci]` 與 `a6b2d187 chore(cd): deploy cc67835 [skip ci]` 生效後補跑 P2-140 production recheck;desktop / mobile 仍確認必要文案可見、水平溢位 `0`、overflowing element `0`、內容區危險控制 `0`、console error `0`、HTTP 4xx/5xx `0`。 - 本波仍不讀 canonical runtime target、不做 live query、不寫 reviewer queue、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不寫 result capture、不寫 learning、不更新 PlayBook trust、不寫 production target、不讀 secret、不執行 destructive action、不回傳內部工作內容;已可由 P2-141 承接,但 P2-141 仍只能推進只讀關卡。 +### 2026-06-14 13:08 (台北) — §3.2 / §5 — 新增 P2-141 release decision input prep — 本地完成決策輸入準備包 + +- 新增 `ai_agent_result_capture_release_decision_input_prep_v1` schema、snapshot、service loader、FastAPI endpoint `GET /api/v1/agents/agent-result-capture-release-decision-input-prep`、governance automation inventory UI 與 i18n 文案。 +- P2-141 承接 P2-140 release decision next handoff,把下一關交接整理成 owner release、verifier、rollback owner、maintenance window、live apply 五類 decision input packet。 +- 本地 rollup:decision input packet `5`、missing input field `15`、blocked input transition `6`、operator action `5`、approval required `12`、blocked + critical `12`、Gateway write `0`、Telegram send `0`、Bot API call `0`、production write `0`。 +- 本地驗證:P2-141 + P2-140 API/service regression `14 passed`、JSON parse、Python compile、i18n key mirror `11864`、source-control owner response guard、security mirror progress guard、doc secret sanity 與 `git diff --check` 通過;本臨時 worktree 無 `node_modules`,Web typecheck 由 Gitea CD 乾淨環境承接。 +- 本波仍不讀 canonical runtime target、不做 live query、不寫 reviewer queue、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不寫 result capture、不寫 learning、不更新 PlayBook trust、不寫 production target、不讀 secret、不執行 destructive action、不回傳內部工作內容;正式驗證後才可由 P2-142 承接。 + ### 2026-06-14 08:36 (台北) — §3.2 / §5 — 正式驗證 P2-134 release authorization hold — 完成釋出授權保留只讀關卡 - Feature commit `e0a6d339` 已由 deploy marker `18b867c3 chore(cd): deploy e0a6d33 [skip ci]` 部署;正式 API health 回 `healthy`、`environment=prod`、`mock_mode=false`。