diff --git a/apps/api/src/api/v1/agents.py b/apps/api/src/api/v1/agents.py index f1094c2de..4bb64a5b9 100644 --- a/apps/api/src/api/v1/agents.py +++ b/apps/api/src/api/v1/agents.py @@ -109,6 +109,9 @@ from src.services.ai_agent_runtime_readback_approval_package import ( from src.services.ai_agent_runtime_readback_implementation_review import ( load_latest_ai_agent_runtime_readback_implementation_review, ) +from src.services.ai_agent_runtime_readback_fixture_approval import ( + load_latest_ai_agent_runtime_readback_fixture_approval, +) from src.services.ai_agent_report_live_delivery_approval_package import ( load_latest_ai_agent_report_live_delivery_approval_package, ) @@ -1392,6 +1395,36 @@ async def get_agent_report_live_delivery_approval_package() -> dict[str, Any]: ) from exc +@router.get( + "/agent-runtime-readback-fixture-approval", + response_model=dict[str, Any], + summary="取得 AI Agent runtime readback fixture 批准包", + description=( + "讀取最新已提交的 P2-112 runtime readback fixture approval package;" + "此端點只回傳 fixture approval card、adapter contract、verifier fixture、" + "blocker mapping 與 operator action,不讀 canonical runtime target、不做 live query、" + "不執行 runtime readback、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、" + "不寫 report receipt、不寫 result capture、不寫 production target、不讀 secret。" + ), +) +async def get_agent_runtime_readback_fixture_approval() -> dict[str, Any]: + """Return the latest read-only runtime readback fixture approval package.""" + try: + payload = await asyncio.to_thread(load_latest_ai_agent_runtime_readback_fixture_approval) + 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_runtime_readback_fixture_approval_invalid", error=str(exc)) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="AI Agent runtime readback fixture approval 無效", + ) from exc + + @router.get( "/agent-owner-approved-fixture-dry-run", response_model=dict[str, Any], diff --git a/apps/api/src/services/ai_agent_runtime_readback_fixture_approval.py b/apps/api/src/services/ai_agent_runtime_readback_fixture_approval.py new file mode 100644 index 000000000..35d6d8f34 --- /dev/null +++ b/apps/api/src/services/ai_agent_runtime_readback_fixture_approval.py @@ -0,0 +1,387 @@ +""" +AI Agent runtime readback fixture approval snapshot. + +Loads the latest committed P2-112 fixture-only runtime readback approval package. +This module validates committed evidence only; it never reads canonical runtime +targets, performs live queries, executes runtime readback, writes Gateway queues, +sends Telegram messages, calls Bot API, writes receipts/result captures, reads +secrets, or performs destructive operations. +""" + +from __future__ import annotations + +import json +from pathlib import Path +from typing import Any + +from src.services.snapshot_paths import default_evaluations_dir + +_DEFAULT_EVALUATIONS_DIR = default_evaluations_dir(Path(__file__)) +_SNAPSHOT_PATTERN = "ai_agent_runtime_readback_fixture_approval_*.json" +_SCHEMA_VERSION = "ai_agent_runtime_readback_fixture_approval_v1" +_RUNTIME_AUTHORITY = "runtime_readback_fixture_approval_only_no_canonical_target_or_live_query" + + +def load_latest_ai_agent_runtime_readback_fixture_approval( + evaluations_dir: Path | None = None, +) -> dict[str, Any]: + """Load the newest committed runtime readback fixture approval package.""" + directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR + candidates = sorted(directory.glob(_SNAPSHOT_PATTERN)) + if not candidates: + raise FileNotFoundError(f"no AI Agent runtime readback fixture approval 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_cards(payload, label) + _require_contracts(payload, label) + _require_checks(payload, label) + _require_blockers(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-112", + "next_task_id": "P2-113", + "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: + runtime = payload.get("prior_runtime_review") or {} + runtime_expected = { + "implementation_review_schema_version": "ai_agent_runtime_readback_implementation_review_v1", + "implementation_review_card_count": 5, + "no_write_verifier_check_count": 5, + "implementation_blocker_count": 5, + "runtime_readback_execution_count": 0, + "live_query_count": 0, + "production_write_count": 0, + } + runtime_mismatches = _mismatches(runtime, runtime_expected) + if runtime_mismatches: + raise ValueError(f"{label}: prior_runtime_review mismatch: {runtime_mismatches}") + if not runtime.get("readiness_note"): + raise ValueError(f"{label}: prior_runtime_review.readiness_note is required") + + delivery = payload.get("prior_delivery_approval") or {} + delivery_expected = { + "delivery_approval_schema_version": "ai_agent_report_live_delivery_approval_package_v1", + "delivery_approval_packet_count": 5, + "route_lock_gate_count": 4, + "payload_redaction_check_count": 5, + "dry_run_delivery_receipt_count": 4, + "telegram_send_count": 0, + "gateway_queue_write_count": 0, + "bot_api_call_count": 0, + } + delivery_mismatches = _mismatches(delivery, delivery_expected) + if delivery_mismatches: + raise ValueError(f"{label}: prior_delivery_approval mismatch: {delivery_mismatches}") + if not delivery.get("readiness_note"): + raise ValueError(f"{label}: prior_delivery_approval.readiness_note is required") + + +def _require_truth(payload: dict[str, Any], label: str) -> None: + truth = payload.get("fixture_approval_truth") or {} + required_true = { + "p2_110_implementation_review_loaded", + "p2_111_delivery_approval_loaded", + "fixture_approval_package_ready", + "adapter_contract_ready", + "verifier_fixture_ready", + "blocker_mapping_ready", + "owner_review_required_before_readback", + } + missing = sorted(field for field in required_true if truth.get(field) is not True) + if missing: + raise ValueError(f"{label}: fixture approval ready flags must remain true: {missing}") + + required_false = { + "canonical_runtime_target_read_enabled", + "live_query_enabled", + "runtime_readback_execution_enabled", + "gateway_queue_write_enabled", + "telegram_send_enabled", + "bot_api_call_enabled", + "report_receipt_write_enabled", + "result_capture_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}: live read/send/write flags must remain false: {unsafe}") + + zero_counts = { + "owner_approval_received_count", + "fixture_readback_execution_count", + "canonical_runtime_target_read_count", + "live_query_count", + "gateway_queue_write_count", + "telegram_send_count", + "bot_api_call_count", + "report_receipt_write_count", + "result_capture_write_count", + "production_write_count", + } + non_zero = sorted(field for field in zero_counts if truth.get(field) != 0) + if non_zero: + raise ValueError(f"{label}: fixture approval live counters must remain zero: {non_zero}") + if not truth.get("truth_note"): + raise ValueError(f"{label}: fixture_approval_truth.truth_note is required") + + +def _require_cards(payload: dict[str, Any], label: str) -> None: + cards = payload.get("fixture_approval_cards") or [] + required = { + "report_delivery_fixture_readback", + "runtime_implementation_fixture_readback", + "telegram_failure_receipt_fixture_readback", + "reviewer_queue_fixture_preview", + "result_capture_fixture_link", + } + card_ids = {card.get("card_id") for card in cards} + if card_ids != required: + raise ValueError(f"{label}: fixture approval cards must match {sorted(required)}") + + for card in cards: + card_id = card.get("card_id") + if card.get("owner_approval_required") is not True or card.get("fixture_only") is not True: + raise ValueError(f"{label}: card {card_id} must require owner approval and fixture_only") + if card.get("status") not in {"approval_required", "ready_for_owner_review", "blocked_by_policy"}: + raise ValueError(f"{label}: card {card_id} status is invalid") + if card.get("risk_tier") not in {"medium", "high", "critical"}: + raise ValueError(f"{label}: card {card_id} risk_tier is invalid") + if not card.get("required_fixture_fields") or not card.get("blocked_runtime_actions"): + raise ValueError(f"{label}: card {card_id} must list fixture fields and blocked actions") + if not _is_redacted_sha256(card.get("evidence_hash")): + raise ValueError(f"{label}: card {card_id} must expose redacted evidence_hash") + + +def _require_contracts(payload: dict[str, Any], label: str) -> None: + contracts = payload.get("adapter_contracts") or [] + required = { + "report_delivery_payload_to_fixture_readback", + "implementation_review_to_adapter_check", + "failure_receipt_to_fixture_verifier", + "result_capture_to_fixture_promotion", + } + contract_ids = {contract.get("contract_id") for contract in contracts} + if contract_ids != required: + raise ValueError(f"{label}: adapter contracts must match {sorted(required)}") + + for contract in contracts: + contract_id = contract.get("contract_id") + if contract.get("status") not in {"ready", "approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: contract {contract_id} status is invalid") + if not contract.get("input_schema") or not contract.get("output_schema"): + raise ValueError(f"{label}: contract {contract_id} input/output schema is required") + if contract.get("canonical_target_read_enabled") is not False or contract.get("live_query_enabled") is not False: + raise ValueError(f"{label}: contract {contract_id} must not enable live target read/query") + if not contract.get("required_evidence"): + raise ValueError(f"{label}: contract {contract_id} required_evidence is required") + if not _is_redacted_sha256(contract.get("evidence_hash")): + raise ValueError(f"{label}: contract {contract_id} must expose redacted evidence_hash") + + +def _require_checks(payload: dict[str, Any], label: str) -> None: + checks = payload.get("verifier_fixture_checks") or [] + required = { + "fixture_payload_shape", + "no_live_target_reference", + "route_lock_fixture", + "redaction_fixture", + "result_capture_no_write_fixture", + } + check_ids = {check.get("check_id") for check in checks} + if check_ids != required: + raise ValueError(f"{label}: verifier fixture checks must match {sorted(required)}") + + for check in checks: + check_id = check.get("check_id") + if check.get("status") not in {"ready", "approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: verifier check {check_id} status is invalid") + if check.get("live_verifier_enabled") is not False: + raise ValueError(f"{label}: verifier check {check_id} must not enable live verifier") + if not check.get("required_fixture") or not check.get("failure_if_missing"): + raise ValueError(f"{label}: verifier check {check_id} must include fixture and failure text") + if not _is_redacted_sha256(check.get("evidence_hash")): + raise ValueError(f"{label}: verifier check {check_id} must expose redacted evidence_hash") + + +def _require_blockers(payload: dict[str, Any], label: str) -> None: + blockers = payload.get("blocker_mappings") or [] + required = { + "canonical_runtime_target_blocked", + "gateway_queue_write_blocked", + "telegram_bot_send_blocked", + "report_receipt_write_blocked", + "result_capture_write_blocked", + } + blocker_ids = {blocker.get("blocker_id") for blocker in blockers} + if blocker_ids != required: + raise ValueError(f"{label}: blocker mappings must match {sorted(required)}") + + for blocker in blockers: + blocker_id = blocker.get("blocker_id") + if blocker.get("severity") not in {"medium", "high", "critical"}: + raise ValueError(f"{label}: blocker {blocker_id} severity is invalid") + if blocker.get("status") not in {"mapped", "approval_required", "blocked_by_policy"}: + raise ValueError(f"{label}: blocker {blocker_id} status is invalid") + if not blocker.get("blocked_action") or not blocker.get("blocked_until"): + raise ValueError(f"{label}: blocker {blocker_id} blocked action/until is required") + if not _is_redacted_sha256(blocker.get("evidence_hash")): + raise ValueError(f"{label}: blocker {blocker_id} must expose redacted evidence_hash") + + +def _require_actions(payload: dict[str, Any], label: str) -> None: + actions = payload.get("operator_actions") or [] + required = { + "review_fixture_approval_cards", + "compare_adapter_contracts", + "confirm_no_live_query", + "reject_canonical_target_scope", + "promote_to_p2_113_fixture_readback", + } + action_ids = {action.get("action_id") for action in actions} + if action_ids != required: + raise ValueError(f"{label}: operator actions must match {sorted(required)}") + + valid_types = { + "review_fixture_approval", + "compare_adapter_contract", + "confirm_no_live_query", + "reject_canonical_target", + "promote_to_p2_113", + } + for action in actions: + action_id = action.get("action_id") + if action.get("action_type") not in valid_types: + raise ValueError(f"{label}: action {action_id} action_type is invalid") + if action.get("runtime_readback_allowed") is not False: + raise ValueError(f"{label}: action {action_id} must not allow runtime readback") + if not action.get("operator_instruction"): + raise ValueError(f"{label}: action {action_id} operator_instruction is required") + + +def _require_display_redaction(payload: dict[str, Any], label: str) -> None: + contract = payload.get("display_redaction_contract") or {} + if contract.get("redaction_required") is not True: + raise ValueError(f"{label}: display redaction must be required") + false_fields = { + "raw_prompt_display_allowed", + "private_reasoning_display_allowed", + "secret_value_display_allowed", + "raw_runtime_payload_display_allowed", + "internal_collaboration_content_display_allowed", + } + unsafe = sorted(field for field in false_fields if contract.get(field) is not False) + if unsafe: + raise ValueError(f"{label}: display redaction flags must remain false: {unsafe}") + if not contract.get("frontend_display_policy"): + raise ValueError(f"{label}: frontend_display_policy is required") + + +def _require_no_forbidden_display_terms(payload: dict[str, Any], label: str) -> None: + serialized = json.dumps(payload, ensure_ascii=False).lower() + forbidden = { + "work_window_transcript", + "session_id", + "browser_context", + "authorization_header", + "raw telegram payload", + "private reasoning", + "raw prompt", + "chain-of-thought", + } + hits = sorted(term for term in forbidden if term in serialized) + if hits: + raise ValueError(f"{label}: forbidden display terms leaked: {hits}") + + +def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None: + rollups = payload.get("rollups") or {} + expected_counts = { + "fixture_approval_card_count": len(payload.get("fixture_approval_cards") or []), + "adapter_contract_count": len(payload.get("adapter_contracts") or []), + "verifier_fixture_check_count": len(payload.get("verifier_fixture_checks") or []), + "blocker_mapping_count": len(payload.get("blocker_mappings") or []), + "operator_action_count": len(payload.get("operator_actions") or []), + "approval_required_card_count": sum( + 1 for card in payload.get("fixture_approval_cards") or [] if card.get("status") == "approval_required" + ), + "blocked_card_count": sum( + 1 for card in payload.get("fixture_approval_cards") or [] if card.get("status") == "blocked_by_policy" + ), + "blocked_contract_count": sum( + 1 for contract in payload.get("adapter_contracts") or [] if contract.get("status") == "blocked_by_policy" + ), + "blocked_check_count": sum( + 1 for check in payload.get("verifier_fixture_checks") or [] if check.get("status") == "blocked_by_policy" + ), + } + mismatches = _mismatches(rollups, expected_counts) + if mismatches: + raise ValueError(f"{label}: rollup counts mismatch: {mismatches}") + + zero_rollups = { + "owner_approval_received_count", + "fixture_readback_execution_count", + "canonical_runtime_target_read_count", + "live_query_count", + "gateway_queue_write_count", + "telegram_send_count", + "bot_api_call_count", + "report_receipt_write_count", + "result_capture_write_count", + "production_write_count", + "secret_read_count", + "destructive_operation_count", + } + non_zero = sorted(field for field in zero_rollups if rollups.get(field) != 0) + if non_zero: + raise ValueError(f"{label}: live/send/write rollups must remain zero: {non_zero}") + + +def _mismatches(actual: dict[str, Any], expected: dict[str, Any]) -> dict[str, dict[str, Any]]: + return { + key: {"expected": expected_value, "actual": actual.get(key)} + for key, expected_value in expected.items() + if actual.get(key) != expected_value + } + + +def _is_redacted_sha256(value: Any) -> bool: + if not isinstance(value, str): + return False + if not value.startswith("sha256:") or len(value) != len("sha256:") + 64: + return False + digest = value.split(":", 1)[1] + return all(char in "0123456789abcdef" for char in digest) diff --git a/apps/api/tests/test_ai_agent_runtime_readback_fixture_approval.py b/apps/api/tests/test_ai_agent_runtime_readback_fixture_approval.py new file mode 100644 index 000000000..f0a2fe0be --- /dev/null +++ b/apps/api/tests/test_ai_agent_runtime_readback_fixture_approval.py @@ -0,0 +1,80 @@ +import copy +import json +from pathlib import Path + +import pytest + +from src.services.ai_agent_runtime_readback_fixture_approval import ( + load_latest_ai_agent_runtime_readback_fixture_approval, +) + + +FIXTURE = Path("docs/evaluations/ai_agent_runtime_readback_fixture_approval_2026-06-13.json") + + +def test_load_latest_ai_agent_runtime_readback_fixture_approval_snapshot() -> None: + data = load_latest_ai_agent_runtime_readback_fixture_approval() + + assert data["schema_version"] == "ai_agent_runtime_readback_fixture_approval_v1" + assert data["program_status"]["current_task_id"] == "P2-112" + assert data["program_status"]["next_task_id"] == "P2-113" + assert data["program_status"]["overall_completion_percent"] == 100 + assert data["program_status"]["read_only_mode"] is True + + rollups = data["rollups"] + assert rollups["fixture_approval_card_count"] == 5 + assert rollups["adapter_contract_count"] == 4 + assert rollups["verifier_fixture_check_count"] == 5 + assert rollups["blocker_mapping_count"] == 5 + assert rollups["operator_action_count"] == 5 + assert rollups["approval_required_card_count"] == 2 + assert rollups["blocked_card_count"] == 1 + assert rollups["blocked_contract_count"] == 1 + assert rollups["blocked_check_count"] == 1 + + zero_fields = [ + "owner_approval_received_count", + "fixture_readback_execution_count", + "canonical_runtime_target_read_count", + "live_query_count", + "gateway_queue_write_count", + "telegram_send_count", + "bot_api_call_count", + "report_receipt_write_count", + "result_capture_write_count", + "production_write_count", + "secret_read_count", + "destructive_operation_count", + ] + for field in zero_fields: + assert rollups[field] == 0 + + +def test_runtime_readback_fixture_approval_rejects_live_query(tmp_path: Path) -> None: + source = json.loads(FIXTURE.read_text(encoding="utf-8")) + source["fixture_approval_truth"]["live_query_enabled"] = True + target = tmp_path / "ai_agent_runtime_readback_fixture_approval_2026-06-13.json" + target.write_text(json.dumps(source), encoding="utf-8") + + with pytest.raises(ValueError, match="live read/send/write flags"): + load_latest_ai_agent_runtime_readback_fixture_approval(tmp_path) + + +def test_runtime_readback_fixture_approval_rejects_rollup_drift(tmp_path: Path) -> None: + source = json.loads(FIXTURE.read_text(encoding="utf-8")) + source["rollups"]["fixture_approval_card_count"] = 4 + target = tmp_path / "ai_agent_runtime_readback_fixture_approval_2026-06-13.json" + target.write_text(json.dumps(source), encoding="utf-8") + + with pytest.raises(ValueError, match="rollup counts mismatch"): + load_latest_ai_agent_runtime_readback_fixture_approval(tmp_path) + + +def test_runtime_readback_fixture_approval_rejects_forbidden_display_terms(tmp_path: Path) -> None: + source = copy.deepcopy(json.loads(FIXTURE.read_text(encoding="utf-8"))) + source["operator_actions"][0]["operator_instruction"] = "do not expose work_window_transcript" + target = tmp_path / "ai_agent_runtime_readback_fixture_approval_2026-06-13.json" + target.write_text(json.dumps(source), encoding="utf-8") + + with pytest.raises(ValueError, match="forbidden display terms"): + load_latest_ai_agent_runtime_readback_fixture_approval(tmp_path) diff --git a/apps/api/tests/test_ai_agent_runtime_readback_fixture_approval_api.py b/apps/api/tests/test_ai_agent_runtime_readback_fixture_approval_api.py new file mode 100644 index 000000000..4df5819a9 --- /dev/null +++ b/apps/api/tests/test_ai_agent_runtime_readback_fixture_approval_api.py @@ -0,0 +1,35 @@ +import pytest +from httpx import ASGITransport, AsyncClient + +from src.main import app + + +@pytest.mark.asyncio +async def test_get_agent_runtime_readback_fixture_approval_api() -> None: + transport = ASGITransport(app=app) + async with AsyncClient(transport=transport, base_url="http://test") as client: + response = await client.get("/api/v1/agents/agent-runtime-readback-fixture-approval") + + assert response.status_code == 200 + data = response.json() + assert data["schema_version"] == "ai_agent_runtime_readback_fixture_approval_v1" + assert data["program_status"]["current_task_id"] == "P2-112" + assert data["program_status"]["next_task_id"] == "P2-113" + assert data["program_status"]["overall_completion_percent"] == 100 + + rollups = data["rollups"] + assert rollups["fixture_approval_card_count"] == 5 + assert rollups["adapter_contract_count"] == 4 + assert rollups["verifier_fixture_check_count"] == 5 + assert rollups["blocker_mapping_count"] == 5 + assert rollups["operator_action_count"] == 5 + assert rollups["owner_approval_received_count"] == 0 + assert rollups["fixture_readback_execution_count"] == 0 + assert rollups["canonical_runtime_target_read_count"] == 0 + assert rollups["live_query_count"] == 0 + assert rollups["gateway_queue_write_count"] == 0 + assert rollups["telegram_send_count"] == 0 + assert rollups["bot_api_call_count"] == 0 + assert rollups["report_receipt_write_count"] == 0 + assert rollups["result_capture_write_count"] == 0 + assert rollups["production_write_count"] == 0 diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 4b02d4d4e..d6db24217 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -953,6 +953,90 @@ "km": "{stale} stale over {days} days", "callback": "missing {missing},1h {recent1h},24h {recent24h}" } + }, + "runtimeReadbackFixtureApproval": { + "title": "P2-112 runtime readback fixture 批准包", + "source": "{generated} · {current} → {next}", + "priorRuntimeTitle": "P2-110 實作審查承接", + "priorDeliveryTitle": "P2-111 實發批准承接", + "truthTitle": "fixture 批准真相", + "metrics": { + "overall": "P2-112 進度", + "cards": "fixture 卡", + "contracts": "adapter contract", + "checks": "verifier fixture", + "blockers": "阻塞映射", + "actions": "操作選項", + "approvalRequired": "需批准", + "blocked": "阻擋總數", + "ownerApprovals": "已收批准", + "executions": "fixture readback", + "canonicalReads": "canonical 讀取", + "liveQueries": "live query", + "gatewayWrites": "Gateway queue", + "telegramSends": "Telegram 發送", + "botCalls": "Bot API", + "receiptWrites": "回執寫入", + "resultWrites": "結果寫入", + "liveWrites": "正式寫入" + }, + "flags": { + "packageReady": "fixture package ready: {value}", + "adapterReady": "adapter contract ready: {value}", + "verifierReady": "verifier fixture ready: {value}", + "canonicalRead": "canonical read: {value}", + "liveQuery": "live query: {value}", + "runtimeExecution": "runtime execution: {value}" + }, + "labels": { + "fixtureFields": "fixture 欄位 {count}", + "blockedActions": "阻擋動作 {count}", + "fixtureOnly": "fixture only: {value}", + "requiredEvidence": "必備證據 {count}", + "canonicalRead": "canonical read: {value}", + "liveQuery": "live query: {value}", + "liveVerifier": "live verifier: {value}", + "blockedAction": "阻擋: {value}", + "blockedUntil": "直到: {value}", + "runtimeReadbackAllowed": "runtime readback: {value}" + }, + "cardStatuses": { + "ready_for_owner_review": "待 owner 審查", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "contractStatuses": { + "ready": "可審查", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "checkStatuses": { + "ready": "可審查", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "blockerStatuses": { + "mapped": "已映射", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "riskTiers": { + "medium": "中風險", + "high": "高風險", + "critical": "關鍵阻擋" + }, + "severities": { + "medium": "中", + "high": "高", + "critical": "關鍵" + }, + "actionTypes": { + "review_fixture_approval": "審查 fixture 批准", + "compare_adapter_contract": "比對 adapter contract", + "confirm_no_live_query": "確認無 live query", + "reject_canonical_target": "退回 canonical target", + "promote_to_p2_113": "推進 P2-113" + } } } }, diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 4b02d4d4e..d6db24217 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -953,6 +953,90 @@ "km": "{stale} stale over {days} days", "callback": "missing {missing},1h {recent1h},24h {recent24h}" } + }, + "runtimeReadbackFixtureApproval": { + "title": "P2-112 runtime readback fixture 批准包", + "source": "{generated} · {current} → {next}", + "priorRuntimeTitle": "P2-110 實作審查承接", + "priorDeliveryTitle": "P2-111 實發批准承接", + "truthTitle": "fixture 批准真相", + "metrics": { + "overall": "P2-112 進度", + "cards": "fixture 卡", + "contracts": "adapter contract", + "checks": "verifier fixture", + "blockers": "阻塞映射", + "actions": "操作選項", + "approvalRequired": "需批准", + "blocked": "阻擋總數", + "ownerApprovals": "已收批准", + "executions": "fixture readback", + "canonicalReads": "canonical 讀取", + "liveQueries": "live query", + "gatewayWrites": "Gateway queue", + "telegramSends": "Telegram 發送", + "botCalls": "Bot API", + "receiptWrites": "回執寫入", + "resultWrites": "結果寫入", + "liveWrites": "正式寫入" + }, + "flags": { + "packageReady": "fixture package ready: {value}", + "adapterReady": "adapter contract ready: {value}", + "verifierReady": "verifier fixture ready: {value}", + "canonicalRead": "canonical read: {value}", + "liveQuery": "live query: {value}", + "runtimeExecution": "runtime execution: {value}" + }, + "labels": { + "fixtureFields": "fixture 欄位 {count}", + "blockedActions": "阻擋動作 {count}", + "fixtureOnly": "fixture only: {value}", + "requiredEvidence": "必備證據 {count}", + "canonicalRead": "canonical read: {value}", + "liveQuery": "live query: {value}", + "liveVerifier": "live verifier: {value}", + "blockedAction": "阻擋: {value}", + "blockedUntil": "直到: {value}", + "runtimeReadbackAllowed": "runtime readback: {value}" + }, + "cardStatuses": { + "ready_for_owner_review": "待 owner 審查", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "contractStatuses": { + "ready": "可審查", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "checkStatuses": { + "ready": "可審查", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "blockerStatuses": { + "mapped": "已映射", + "approval_required": "需批准", + "blocked_by_policy": "政策阻擋" + }, + "riskTiers": { + "medium": "中風險", + "high": "高風險", + "critical": "關鍵阻擋" + }, + "severities": { + "medium": "中", + "high": "高", + "critical": "關鍵" + }, + "actionTypes": { + "review_fixture_approval": "審查 fixture 批准", + "compare_adapter_contract": "比對 adapter contract", + "confirm_no_live_query": "確認無 live query", + "reject_canonical_target": "退回 canonical target", + "promote_to_p2_113": "推進 P2-113" + } } } }, 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 e3ed15a61..db841315b 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 @@ -59,6 +59,7 @@ import { type AiAgentReportRuntimeReadinessSnapshot, type AiAgentReportTruthActionabilityReviewSnapshot, type AiAgentRuntimeReadbackApprovalPackageSnapshot, + type AiAgentRuntimeReadbackFixtureApprovalSnapshot, type AiAgentRuntimeReadbackImplementationReviewSnapshot, type AiAgentRuntimeWorkerShadowGateSnapshot, type AiAgentRuntimeVerifierEvidenceReviewSnapshot, @@ -440,6 +441,7 @@ export function AutomationInventoryTab() { const [runtimeReadbackApprovalPackage, setRuntimeReadbackApprovalPackage] = useState(null) const [runtimeReadbackImplementationReview, setRuntimeReadbackImplementationReview] = useState(null) const [reportLiveDeliveryApprovalPackage, setReportLiveDeliveryApprovalPackage] = useState(null) + const [runtimeReadbackFixtureApproval, setRuntimeReadbackFixtureApproval] = useState(null) const [reportTruthActionabilityReview, setReportTruthActionabilityReview] = useState(null) const [ownerDryRunPackage, setOwnerDryRunPackage] = useState(null) const [hostStatefulInventory, setHostStatefulInventory] = useState(null) @@ -488,6 +490,7 @@ export function AutomationInventoryTab() { apiClient.getAiAgentRuntimeReadbackApprovalPackage(), apiClient.getAiAgentRuntimeReadbackImplementationReview(), apiClient.getAiAgentReportLiveDeliveryApprovalPackage(), + apiClient.getAiAgentRuntimeReadbackFixtureApproval(), apiClient.getAiAgentReportTruthActionabilityReview(), apiClient.getAiAgentOwnerApprovedFixtureDryRun(), apiClient.getAiAgentHostStatefulVersionInventory(), @@ -535,6 +538,7 @@ export function AutomationInventoryTab() { runtimeReadbackApprovalPackageResult, runtimeReadbackImplementationReviewResult, reportLiveDeliveryApprovalPackageResult, + runtimeReadbackFixtureApprovalResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -579,6 +583,7 @@ export function AutomationInventoryTab() { setRuntimeReadbackApprovalPackage(runtimeReadbackApprovalPackageResult.status === 'fulfilled' ? runtimeReadbackApprovalPackageResult.value : null) setRuntimeReadbackImplementationReview(runtimeReadbackImplementationReviewResult.status === 'fulfilled' ? runtimeReadbackImplementationReviewResult.value : null) setReportLiveDeliveryApprovalPackage(reportLiveDeliveryApprovalPackageResult.status === 'fulfilled' ? reportLiveDeliveryApprovalPackageResult.value : null) + setRuntimeReadbackFixtureApproval(runtimeReadbackFixtureApprovalResult.status === 'fulfilled' ? runtimeReadbackFixtureApprovalResult.value : null) setReportTruthActionabilityReview(reportTruthActionabilityReviewResult.status === 'fulfilled' ? reportTruthActionabilityReviewResult.value : null) setOwnerDryRunPackage(ownerDryRunPackageResult.status === 'fulfilled' ? ownerDryRunPackageResult.value : null) setHostStatefulInventory(hostStatefulInventoryResult.status === 'fulfilled' ? hostStatefulInventoryResult.value : null) @@ -621,6 +626,7 @@ export function AutomationInventoryTab() { runtimeReadbackApprovalPackageResult, runtimeReadbackImplementationReviewResult, reportLiveDeliveryApprovalPackageResult, + runtimeReadbackFixtureApprovalResult, reportTruthActionabilityReviewResult, ownerDryRunPackageResult, hostStatefulInventoryResult, @@ -1863,7 +1869,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 || !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 || !reportTruthActionabilityReview || !ownerDryRunPackage || !hostStatefulInventory || !serviceHealthGapMatrix || !serviceHealthNotificationPolicy) { return (
@@ -2271,6 +2277,38 @@ export function AutomationInventoryTab() { + reportLiveDeliveryApprovalPackage.rollups.auto_optimization_count + reportLiveDeliveryApprovalPackage.rollups.production_write_count ) + const fixtureApprovalOverall = runtimeReadbackFixtureApproval.program_status.overall_completion_percent + const fixtureApprovalCards = runtimeReadbackFixtureApproval.rollups.fixture_approval_card_count + const fixtureApprovalContracts = runtimeReadbackFixtureApproval.rollups.adapter_contract_count + const fixtureApprovalChecks = runtimeReadbackFixtureApproval.rollups.verifier_fixture_check_count + const fixtureApprovalBlockers = runtimeReadbackFixtureApproval.rollups.blocker_mapping_count + const fixtureApprovalActions = runtimeReadbackFixtureApproval.rollups.operator_action_count + const fixtureApprovalRequired = runtimeReadbackFixtureApproval.rollups.approval_required_card_count + const fixtureApprovalBlocked = ( + runtimeReadbackFixtureApproval.rollups.blocked_card_count + + runtimeReadbackFixtureApproval.rollups.blocked_contract_count + + runtimeReadbackFixtureApproval.rollups.blocked_check_count + ) + const fixtureApprovalOwnerApprovals = runtimeReadbackFixtureApproval.rollups.owner_approval_received_count + const fixtureApprovalExecutions = runtimeReadbackFixtureApproval.rollups.fixture_readback_execution_count + const fixtureApprovalCanonicalReads = runtimeReadbackFixtureApproval.rollups.canonical_runtime_target_read_count + const fixtureApprovalLiveQueries = runtimeReadbackFixtureApproval.rollups.live_query_count + const fixtureApprovalGatewayWrites = runtimeReadbackFixtureApproval.rollups.gateway_queue_write_count + const fixtureApprovalTelegramSends = runtimeReadbackFixtureApproval.rollups.telegram_send_count + const fixtureApprovalBotCalls = runtimeReadbackFixtureApproval.rollups.bot_api_call_count + const fixtureApprovalReceiptWrites = runtimeReadbackFixtureApproval.rollups.report_receipt_write_count + const fixtureApprovalResultWrites = runtimeReadbackFixtureApproval.rollups.result_capture_write_count + const fixtureApprovalLiveWrites = ( + runtimeReadbackFixtureApproval.rollups.fixture_readback_execution_count + + runtimeReadbackFixtureApproval.rollups.canonical_runtime_target_read_count + + runtimeReadbackFixtureApproval.rollups.live_query_count + + runtimeReadbackFixtureApproval.rollups.gateway_queue_write_count + + runtimeReadbackFixtureApproval.rollups.telegram_send_count + + runtimeReadbackFixtureApproval.rollups.bot_api_call_count + + runtimeReadbackFixtureApproval.rollups.report_receipt_write_count + + runtimeReadbackFixtureApproval.rollups.result_capture_write_count + + runtimeReadbackFixtureApproval.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 @@ -5554,6 +5592,194 @@ export function AutomationInventoryTab() {
+
+
+
+ + + {t('runtimeReadbackFixtureApproval.title')} + +
+ +
+ +
+ } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> +
+ +
+
+ {t('runtimeReadbackFixtureApproval.priorRuntimeTitle')} + + {runtimeReadbackFixtureApproval.prior_runtime_review.readiness_note} + +
+ + + + +
+
+ +
+ {t('runtimeReadbackFixtureApproval.priorDeliveryTitle')} + + {runtimeReadbackFixtureApproval.prior_delivery_approval.readiness_note} + +
+ + + + +
+
+ +
+ {t('runtimeReadbackFixtureApproval.truthTitle')} + + {runtimeReadbackFixtureApproval.fixture_approval_truth.truth_note} + +
+ + + + + + +
+
+
+ +
+ {runtimeReadbackFixtureApproval.fixture_approval_cards.map(card => ( +
+
+ + {card.display_name} + + +
+ + {card.operator_guidance} + +
+ + + + + + +
+
+ ))} +
+ +
+ {runtimeReadbackFixtureApproval.adapter_contracts.map(contract => ( +
+
+ + {contract.display_name} + + +
+
+ + + + + +
+
+ ))} +
+ +
+ {runtimeReadbackFixtureApproval.verifier_fixture_checks.map(check => ( +
+
+ + {check.display_name} + + +
+ + {check.failure_if_missing} + +
+ + +
+
+ ))} +
+ +
+ {runtimeReadbackFixtureApproval.blocker_mappings.map(blocker => ( +
+
+ + {blocker.display_name} + + +
+ + {blocker.source_blocker} + +
+ + + +
+
+ ))} +
+ +
+ {runtimeReadbackFixtureApproval.operator_actions.map(action => ( +
+
+ + {action.display_name} + + +
+ + {action.operator_instruction} + +
+ + +
+
+ ))} +
+
+
diff --git a/apps/web/src/lib/api-client.ts b/apps/web/src/lib/api-client.ts index f82d1e865..3620fb541 100644 --- a/apps/web/src/lib/api-client.ts +++ b/apps/web/src/lib/api-client.ts @@ -455,6 +455,11 @@ export const apiClient = { return handleResponse(res) }, + async getAiAgentRuntimeReadbackFixtureApproval() { + const res = await fetch(`${API_BASE_URL}/agents/agent-runtime-readback-fixture-approval`) + return handleResponse(res) + }, + async getAiAgentOwnerApprovedFixtureDryRun() { const res = await fetch(`${API_BASE_URL}/agents/agent-owner-approved-fixture-dry-run`) return handleResponse(res) @@ -4303,6 +4308,157 @@ export interface AiAgentReportLiveDeliveryApprovalPackageSnapshot { } } +export interface AiAgentRuntimeReadbackFixtureApprovalSnapshot { + schema_version: 'ai_agent_runtime_readback_fixture_approval_v1' + generated_at: string + program_status: { + overall_completion_percent: number + current_priority: 'P0' | 'P1' | 'P2' | 'P3' + current_task_id: 'P2-112' + next_task_id: 'P2-113' + read_only_mode: true + runtime_authority: 'runtime_readback_fixture_approval_only_no_canonical_target_or_live_query' + status_note: string + } + source_refs: string[] + prior_runtime_review: { + implementation_review_schema_version: 'ai_agent_runtime_readback_implementation_review_v1' + implementation_review_card_count: number + no_write_verifier_check_count: number + implementation_blocker_count: number + runtime_readback_execution_count: number + live_query_count: number + production_write_count: number + readiness_note: string + } + prior_delivery_approval: { + delivery_approval_schema_version: 'ai_agent_report_live_delivery_approval_package_v1' + delivery_approval_packet_count: number + route_lock_gate_count: number + payload_redaction_check_count: number + dry_run_delivery_receipt_count: number + telegram_send_count: number + gateway_queue_write_count: number + bot_api_call_count: number + readiness_note: string + } + fixture_approval_truth: { + p2_110_implementation_review_loaded: true + p2_111_delivery_approval_loaded: true + fixture_approval_package_ready: true + adapter_contract_ready: true + verifier_fixture_ready: true + blocker_mapping_ready: true + owner_review_required_before_readback: true + canonical_runtime_target_read_enabled: false + live_query_enabled: false + runtime_readback_execution_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 + production_write_enabled: false + secret_read_enabled: false + destructive_operation_enabled: false + owner_approval_received_count: number + fixture_readback_execution_count: number + canonical_runtime_target_read_count: number + live_query_count: number + gateway_queue_write_count: number + telegram_send_count: number + bot_api_call_count: number + report_receipt_write_count: number + result_capture_write_count: number + production_write_count: number + truth_note: string + } + fixture_approval_cards: Array<{ + card_id: string + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + source_task_id: 'P2-110' | 'P2-111' + status: 'approval_required' | 'ready_for_owner_review' | 'blocked_by_policy' + risk_tier: 'medium' | 'high' | 'critical' + required_fixture_fields: string[] + blocked_runtime_actions: string[] + operator_guidance: string + owner_approval_required: true + fixture_only: true + evidence_hash: string + }> + adapter_contracts: Array<{ + contract_id: string + display_name: string + status: 'ready' | 'approval_required' | 'blocked_by_policy' + input_schema: string + output_schema: string + required_evidence: string[] + canonical_target_read_enabled: false + live_query_enabled: false + evidence_hash: string + }> + verifier_fixture_checks: Array<{ + check_id: string + display_name: string + status: 'ready' | 'approval_required' | 'blocked_by_policy' + required_fixture: string + failure_if_missing: string + live_verifier_enabled: false + evidence_hash: string + }> + blocker_mappings: Array<{ + blocker_id: string + display_name: string + source_blocker: string + severity: 'medium' | 'high' | 'critical' + blocked_action: string + blocked_until: string + status: 'mapped' | 'approval_required' | 'blocked_by_policy' + evidence_hash: string + }> + operator_actions: Array<{ + action_id: string + display_name: string + owner_agent: 'openclaw' | 'hermes' | 'nemotron' + action_type: 'review_fixture_approval' | 'compare_adapter_contract' | 'confirm_no_live_query' | 'reject_canonical_target' | 'promote_to_p2_113' + operator_instruction: string + runtime_readback_allowed: false + }> + display_redaction_contract: { + redaction_required: true + frontend_display_policy: string + 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 + } + rollups: { + fixture_approval_card_count: number + adapter_contract_count: number + verifier_fixture_check_count: number + blocker_mapping_count: number + operator_action_count: number + approval_required_card_count: number + blocked_card_count: number + blocked_contract_count: number + blocked_check_count: number + owner_approval_received_count: number + fixture_readback_execution_count: number + canonical_runtime_target_read_count: number + live_query_count: number + gateway_queue_write_count: number + telegram_send_count: number + bot_api_call_count: number + report_receipt_write_count: number + result_capture_write_count: number + production_write_count: number + secret_read_count: number + destructive_operation_count: number + } +} + export interface AiAgentOwnerApprovedFixtureDryRunSnapshot { schema_version: 'ai_agent_owner_approved_fixture_dry_run_v1' generated_at: string diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index 2e920121e..436e03950 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,27 @@ +## 2026-06-13|P2-112 Runtime readback fixture approval 本地完成 + +**背景**:P2-111 已把日報 / 週報 / 月報、失敗限定摘要與讀報回執整理成 report live delivery approval package;但下一步仍不能直接讀 canonical runtime target、做 live query、寫 Gateway queue 或送 Telegram。P2-112 先把 P2-110 implementation review 與 P2-111 delivery approval 轉成 fixture-only runtime readback 批准包。 + +**完成內容**: +- 新增 `ai_agent_runtime_readback_fixture_approval_v1` schema、committed snapshot、loader 與 API endpoint `GET /api/v1/agents/agent-runtime-readback-fixture-approval`。 +- P2-112 snapshot 固定 5 張 fixture approval card、4 個 adapter contract、5 個 verifier fixture check、5 個 blocker mapping 與 5 個 operator action。 +- Governance automation inventory 頁新增 P2-112 區塊,顯示 P2-112 進度 `100%`、fixture 卡 `5`、adapter contract `4`、verifier fixture `5`、阻塞映射 `5`、操作選項 `5`、需批准 `2`、阻擋總數 `3`、owner approval received `0`、fixture readback execution `0`、canonical runtime target read `0`、live query `0`、Gateway queue `0`、Telegram send `0`、Bot API `0`、report receipt write `0`、result capture write `0` 與 live writes `0`。 +- `docs/evaluations/ai_agent_runtime_readback_fixture_approval_2026-06-13.json` 已清除 forbidden display terms,guard 會拒絕 `work_window_transcript`、`session_id`、`browser_context`、`authorization_header`、`raw Telegram payload`、`private reasoning`、`raw prompt` 與 `chain-of-thought` 類字串外露。 + +**本地驗證**: +- JSON parse:P2-112 schema / snapshot、`zh-TW.json`、`en.json` 通過。 +- Python 編譯:P2-112 loader 與 `agents.py` 通過。 +- API/service pytest:P2-111 + P2-112 目標組 `15 passed`。 +- i18n mirror / placeholder:`10946` leaves,diff `0`。 +- Web typecheck:`pnpm --filter @awoooi/web typecheck` 通過。 +- `source-control-owner-response-guard.py`、`security-mirror-progress-guard.py`、`doc-secrets-sanity-check.py docs .gitea`、`git diff --check` 通過。 + +**安全邊界**: +- P2-112 仍是 fixture-only approval package;不讀 canonical runtime target、不做 live query、不執行 runtime readback、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不寫 result capture、不寫 production target、不讀 secret、不執行 destructive action。 + +**下一步**: +- 推送 Gitea 後等待 deploy marker,完成正式 API readback 與 desktop / mobile governance smoke;正式站通過後再補 production 記錄。 + ## 2026-06-13|P2-111 Report live delivery approval package 本地完成與正式驗證 **背景**:P2-108 已讓日報 / 週報 / 月報與 Agent 工作量可見,P2-109 / P2-110 已把 runtime readback approval package 與 implementation review 固定成 no-write gate;但週報全 0、Telegram 未實發與 AwoooI SRE 戰情室收斂仍缺少一個可審查的「實發批准包」。 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 c6413bcfc..275f3ff8f 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 已完成只讀 contract;P2-403A 已完成互動 / 接手 / 學習 / 成長證據面板;P2-403B 已完成 AgentSession / Redis Streams live read model gate;P2-403C 已完成 Redis Streams consumer group dry-run、handoff envelope、ack / dead-letter / replay gate;P2-403D 已完成 learning writeback approval package;P2-403E 已完成 Telegram receipt approval package;P2-403F 已完成 owner-approved learning dry-run preview、人工操作選項與 fixture-only dry-run 總包;P2-403G 已完成 runtime write gate review;P2-403H 已完成 post-write verifier implementation package;P2-403I 已完成 runtime verifier evidence implementation review;P2-403J 已完成報表真相 / 告警有效性 / 日週月報 / Agent 工作量 / 圖表化報告 / AI 建議 / 風險自動化政策審查;P2-403K / L / M / N 已把 SRE 戰情室路由、報表派送啟動前閘門、no-write dry-run 與 fixture/readback/verifier dry-run 固定;P2-404 已完成 runtime worker shadow / no-write evidence;P2-101 已完成操作類別權限模型;P2-102 已完成 13 類候選操作 dry-run 證據;P2-103 已完成任務結果稽核軌跡;P2-104 已完成 matched PlayBook 學習缺口回查;P2-105 已完成 critic / reviewer 評分與 result capture 契約;P2-106 已完成 owner-approved result capture dry-run;P2-107 已完成 owner-approved result capture readback / promotion readiness;P2-108 已完成日週月報與 Agent 工作狀態總覽;P2-109 已完成 runtime readback approval package;P2-110 已完成 runtime readback implementation review 並正式驗證;P2-111 已完成 report live delivery approval package 並正式驗證,固定 5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt 與 5 個 operator action。runtime worker、DB migration、production Redis consumer group、canonical runtime readback、live query、runtime score、result capture write、Telegram 實發、delivery receipt E2E、live report delivery、reviewer queue write、Gateway queue write、AI analysis runtime、中低風險 auto worker、KM / LOGBOOK / audit DB / timeline / PlayBook trust 寫入、SDK / 付費服務仍未開 gate | `ai_agent_communication_learning_contract_v1`、`ai_agent_interaction_learning_proof_v1`、`ai_agent_operation_permission_model_v1`、`ai_agent_candidate_operation_dry_run_evidence_v1`、`ai_agent_task_result_audit_trail_v1`、`ai_agent_matched_playbook_learning_gap_v1`、`ai_agent_critic_reviewer_result_capture_v1`、`ai_agent_owner_approved_result_capture_dry_run_v1`、`ai_agent_owner_approved_result_capture_readback_v1`、`ai_agent_report_status_board_v1`、`ai_agent_runtime_readback_approval_package_v1`、`ai_agent_runtime_readback_implementation_review_v1`、`ai_agent_report_live_delivery_approval_package_v1`、`GET /api/v1/agents/agent-operation-permission-model`、`GET /api/v1/agents/agent-candidate-operation-dry-run-evidence`、`GET /api/v1/agents/agent-task-result-audit-trail`、`GET /api/v1/agents/agent-matched-playbook-learning-gap`、`GET /api/v1/agents/agent-critic-reviewer-result-capture`、`GET /api/v1/agents/agent-owner-approved-result-capture-dry-run`、`GET /api/v1/agents/agent-owner-approved-result-capture-readback`、`GET /api/v1/agents/agent-report-status-board`、`GET /api/v1/agents/agent-runtime-readback-approval-package`、`GET /api/v1/agents/agent-runtime-readback-implementation-review`、`GET /api/v1/agents/agent-report-live-delivery-approval-package`、`/zh-TW/governance?tab=automation-inventory`、MASTER §3.2.1b / §3.2.1d / §3.4.3 | +| OpenClaw / Hermes / NemoTron 主動溝通、學習與成長證據 | 100% | P2-401A 已完成只讀 contract;P2-403A 已完成互動 / 接手 / 學習 / 成長證據面板;P2-403B 已完成 AgentSession / Redis Streams live read model gate;P2-403C 已完成 Redis Streams consumer group dry-run、handoff envelope、ack / dead-letter / replay gate;P2-403D 已完成 learning writeback approval package;P2-403E 已完成 Telegram receipt approval package;P2-403F 已完成 owner-approved learning dry-run preview、人工操作選項與 fixture-only dry-run 總包;P2-403G 已完成 runtime write gate review;P2-403H 已完成 post-write verifier implementation package;P2-403I 已完成 runtime verifier evidence implementation review;P2-403J 已完成報表真相 / 告警有效性 / 日週月報 / Agent 工作量 / 圖表化報告 / AI 建議 / 風險自動化政策審查;P2-403K / L / M / N 已把 SRE 戰情室路由、報表派送啟動前閘門、no-write dry-run 與 fixture/readback/verifier dry-run 固定;P2-404 已完成 runtime worker shadow / no-write evidence;P2-101 已完成操作類別權限模型;P2-102 已完成 13 類候選操作 dry-run 證據;P2-103 已完成任務結果稽核軌跡;P2-104 已完成 matched PlayBook 學習缺口回查;P2-105 已完成 critic / reviewer 評分與 result capture 契約;P2-106 已完成 owner-approved result capture dry-run;P2-107 已完成 owner-approved result capture readback / promotion readiness;P2-108 已完成日週月報與 Agent 工作狀態總覽;P2-109 已完成 runtime readback approval package;P2-110 已完成 runtime readback implementation review 並正式驗證;P2-111 已完成 report live delivery approval package 並正式驗證;P2-112 已本地完成 runtime readback fixture approval,固定 5 張 fixture card、4 個 adapter contract、5 個 verifier fixture check、5 個 blocker mapping 與 5 個 operator action。runtime worker、DB migration、production Redis consumer group、canonical runtime readback、live query、runtime score、result capture write、Telegram 實發、delivery receipt E2E、live report delivery、reviewer queue write、Gateway queue write、AI analysis runtime、中低風險 auto worker、KM / LOGBOOK / audit DB / timeline / PlayBook trust 寫入、SDK / 付費服務仍未開 gate | `ai_agent_communication_learning_contract_v1`、`ai_agent_interaction_learning_proof_v1`、`ai_agent_operation_permission_model_v1`、`ai_agent_candidate_operation_dry_run_evidence_v1`、`ai_agent_task_result_audit_trail_v1`、`ai_agent_matched_playbook_learning_gap_v1`、`ai_agent_critic_reviewer_result_capture_v1`、`ai_agent_owner_approved_result_capture_dry_run_v1`、`ai_agent_owner_approved_result_capture_readback_v1`、`ai_agent_report_status_board_v1`、`ai_agent_runtime_readback_approval_package_v1`、`ai_agent_runtime_readback_implementation_review_v1`、`ai_agent_report_live_delivery_approval_package_v1`、`ai_agent_runtime_readback_fixture_approval_v1`、`GET /api/v1/agents/agent-operation-permission-model`、`GET /api/v1/agents/agent-candidate-operation-dry-run-evidence`、`GET /api/v1/agents/agent-task-result-audit-trail`、`GET /api/v1/agents/agent-matched-playbook-learning-gap`、`GET /api/v1/agents/agent-critic-reviewer-result-capture`、`GET /api/v1/agents/agent-owner-approved-result-capture-dry-run`、`GET /api/v1/agents/agent-owner-approved-result-capture-readback`、`GET /api/v1/agents/agent-report-status-board`、`GET /api/v1/agents/agent-runtime-readback-approval-package`、`GET /api/v1/agents/agent-runtime-readback-implementation-review`、`GET /api/v1/agents/agent-report-live-delivery-approval-package`、`GET /api/v1/agents/agent-runtime-readback-fixture-approval`、`/zh-TW/governance?tab=automation-inventory`、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 文件 | @@ -20,9 +20,9 @@ AI Agent 自動化工作包目前完成度:**94%**。本工作清單文件本 三 Agent 佈建布局目前完成度:**45%**。第一波已完成只讀 schema / snapshot / API / 測試 / 報告,第二波已接入治理頁自動化盤點 UI;正式 runtime 佈署、Telegram E2E 發送與 AgentSession 工作流仍需逐項 gate。 -三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。已完成只讀契約、互動 / 接手 / 學習 / 成長證據面板、P2-403B live read model gate、P2-403C Redis dry-run gate、P2-403D learning writeback approval package、P2-403E Telegram receipt approval package、P2-403F owner-approved learning dry-run preview、P2-403G runtime write gate review、P2-403H post-write verifier implementation package、P2-403I runtime verifier evidence implementation review、P2-403J 報表真相 / 告警有效性 / 日週月報 / Agent 工作量 / 圖表化報告 / AI 建議 / 風險自動化政策審查、P2-403K/L/M/N 報表與 SRE 戰情室 dry-run 鏈、P2-404 runtime worker shadow / no-write execution evidence gate、P2-101 操作類別權限模型、P2-102 候選操作 dry-run 證據、P2-103 任務結果稽核軌跡、P2-104 matched PlayBook 學習缺口回查、P2-105 critic / reviewer 評分與 result capture 契約、P2-106 owner-approved result capture dry-run、P2-107 owner-approved result capture readback / promotion readiness、P2-108 日週月報與 Agent 工作狀態總覽、P2-109 runtime readback approval package、P2-110 runtime readback implementation review 正式驗證,以及 P2-111 report live delivery approval package 正式驗證。目前 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-111 已固定 5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt 與 5 個 operator action;真正下一步是 `P2-112`。 +三 Agent 主動溝通、學習與成長證據目前完成度:**100%**。已完成只讀契約、互動 / 接手 / 學習 / 成長證據面板、P2-403B live read model gate、P2-403C Redis dry-run gate、P2-403D learning writeback approval package、P2-403E Telegram receipt approval package、P2-403F owner-approved learning dry-run preview、P2-403G runtime write gate review、P2-403H post-write verifier implementation package、P2-403I runtime verifier evidence implementation review、P2-403J 報表真相 / 告警有效性 / 日週月報 / Agent 工作量 / 圖表化報告 / AI 建議 / 風險自動化政策審查、P2-403K/L/M/N 報表與 SRE 戰情室 dry-run 鏈、P2-404 runtime worker shadow / no-write execution evidence gate、P2-101 操作類別權限模型、P2-102 候選操作 dry-run 證據、P2-103 任務結果稽核軌跡、P2-104 matched PlayBook 學習缺口回查、P2-105 critic / reviewer 評分與 result capture 契約、P2-106 owner-approved result capture dry-run、P2-107 owner-approved result capture readback / promotion readiness、P2-108 日週月報與 Agent 工作狀態總覽、P2-109 runtime readback approval package、P2-110 runtime readback implementation review 正式驗證、P2-111 report live delivery approval package 正式驗證,以及 P2-112 runtime readback fixture approval 本地完成。目前 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-112 已固定 5 張 fixture card、4 個 adapter contract、5 個 verifier fixture check、5 個 blocker mapping 與 5 個 operator action;真正下一步是 `P2-113`。 -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-111` 已補互動、學習證據面、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、owner-approved result capture readback / promotion readiness、Agent report status board、runtime readback approval package、runtime readback implementation review 與 report live delivery approval package。下一步是 `P2-112`;外部 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-112` 已補互動、學習證據面、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、owner-approved result capture readback / promotion readiness、Agent report status board、runtime readback approval package、runtime readback implementation review、report live delivery approval package 與 runtime readback fixture approval。下一步是 `P2-113`;外部 registry / package source / host probe / SSH / kubectl / 工具安裝 / CI 變更 / 實際 PR creation / Telegram 實發與 learning write 仍需 gate。 完成度計算模型: diff --git a/docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md b/docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md index 60e0dbe4d..b6dd0a242 100644 --- a/docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md +++ b/docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md @@ -1,8 +1,8 @@ # AI Agent 互動、溝通、學習與成長證據報告 > 日期:2026-06-11(台北時間) -> 文件定位:P2-403A 證據面 + P2-403B AgentSession / Redis Streams live read model gate + P2-403C Redis dry-run gate + P2-403D learning writeback approval package + P2-403E Telegram receipt approval package + P2-403F owner-approved learning dry-run / fixture dry-run、P2-403G runtime write gate review、P2-403H post-write verifier package、P2-403I runtime verifier evidence implementation review、P2-403J 報表真相 / 日週月報 / Agent 工作量 / 風險自動化 review、P2-403L 報表派送與自動處理啟動前閘門、P2-403M 報表 runtime no-write dry-run 證據包、P2-403N fixture smoke / queue preview readback / verifier dry-run、P2-404 runtime worker shadow / no-write execution evidence gate、P2-101 操作類別權限模型、P2-102 候選操作 dry-run 證據、P2-103 任務結果稽核軌跡、P2-104 matched PlayBook 學習缺口、P2-105 critic / reviewer 評分與 result capture、P2-106 / P2-107 owner-approved result capture dry-run / readback、P2-108 日週月報與 Agent 工作狀態總覽、P2-111 report live delivery approval package、API 與治理頁 UI。 -> 事實邊界:本波只建立可見證據面、read model gate、報表治理 review、runtime readiness gate、no-write dry-run、fixture/readback/verifier dry-run、shadow/no-write execution 證據包、operation permission lane、candidate dry-run evidence、result audit trail、matched PlayBook learning gap readback、critic / reviewer result capture gate、report status board 與 report live delivery approval package,不啟動 runtime worker、不建立 DB migration、不開 Redis consumer group、不發 Telegram、不寫 Gateway queue、不寫 delivery receipt、不排程實發報告、不啟動中低風險 auto worker、不執行 verifier live readback、不寫 KM、不 runtime append LOGBOOK、不寫 audit DB、不寫 timeline、不更新 PlayBook trust、不執行生產優化、不顯示內部協作內容。 +> 文件定位:P2-403A 證據面 + P2-403B AgentSession / Redis Streams live read model gate + P2-403C Redis dry-run gate + P2-403D learning writeback approval package + P2-403E Telegram receipt approval package + P2-403F owner-approved learning dry-run / fixture dry-run、P2-403G runtime write gate review、P2-403H post-write verifier package、P2-403I runtime verifier evidence implementation review、P2-403J 報表真相 / 日週月報 / Agent 工作量 / 風險自動化 review、P2-403L 報表派送與自動處理啟動前閘門、P2-403M 報表 runtime no-write dry-run 證據包、P2-403N fixture smoke / queue preview readback / verifier dry-run、P2-404 runtime worker shadow / no-write execution evidence gate、P2-101 操作類別權限模型、P2-102 候選操作 dry-run 證據、P2-103 任務結果稽核軌跡、P2-104 matched PlayBook 學習缺口、P2-105 critic / reviewer 評分與 result capture、P2-106 / P2-107 owner-approved result capture dry-run / readback、P2-108 日週月報與 Agent 工作狀態總覽、P2-111 report live delivery approval package、P2-112 runtime readback fixture approval、API 與治理頁 UI。 +> 事實邊界:本波只建立可見證據面、read model gate、報表治理 review、runtime readiness gate、no-write dry-run、fixture/readback/verifier dry-run、shadow/no-write execution 證據包、operation permission lane、candidate dry-run evidence、result audit trail、matched PlayBook learning gap readback、critic / reviewer result capture gate、report status board、report live delivery approval package 與 runtime readback fixture approval,不啟動 runtime worker、不建立 DB migration、不開 Redis consumer group、不發 Telegram、不寫 Gateway queue、不寫 delivery receipt、不排程實發報告、不啟動中低風險 auto worker、不執行 verifier live readback、不讀 canonical runtime target、不做 live query、不寫 result capture、不寫 KM、不 runtime append LOGBOOK、不寫 audit DB、不寫 timeline、不更新 PlayBook trust、不執行生產優化、不顯示內部協作內容。 ## 0. P2-403J 補記:報表真相、日週月報與風險自動化 Review @@ -66,7 +66,7 @@ ## 1. 結論 -已完成 P2-403A、P2-403B、P2-403C、P2-403D、P2-403E、P2-403F、P2-403G、P2-403H、P2-403I、P2-403J、P2-403L、P2-403M、P2-403N、P2-404、P2-101、P2-102、P2-103、P2-104、P2-105、P2-106、P2-107、P2-108、P2-109、P2-110 與 P2-111:讓統帥能在治理頁看到 OpenClaw / Hermes / NemoTron 的互動、接手、學習與成長是否真的有證據,並看到 live read model、Redis dry-run、handoff envelope、ack / dead-letter / replay、learning writeback approval、Telegram receipt approval、fixture dry-run、runtime write gate review、post-write verifier package、runtime verifier evidence review、報表真相、日週月報、Agent 工作量、圖表化報告、風險自動化政策、報表 runtime 啟動前閘門、no-write dry-run 證據包、fixture/readback/verifier dry-run 證據包、shadow/no-write execution evidence gate、操作類別權限模型、候選操作 dry-run 證據、任務結果稽核軌跡、matched PlayBook 學習缺口、critic / reviewer result capture gate、owner-approved result capture dry-run / readback、日週月報工作狀態總覽、runtime readback approval / implementation review,以及 report live delivery approval package。 +已完成 P2-403A、P2-403B、P2-403C、P2-403D、P2-403E、P2-403F、P2-403G、P2-403H、P2-403I、P2-403J、P2-403L、P2-403M、P2-403N、P2-404、P2-101、P2-102、P2-103、P2-104、P2-105、P2-106、P2-107、P2-108、P2-109、P2-110、P2-111 與 P2-112:讓統帥能在治理頁看到 OpenClaw / Hermes / NemoTron 的互動、接手、學習與成長是否真的有證據,並看到 live read model、Redis dry-run、handoff envelope、ack / dead-letter / replay、learning writeback approval、Telegram receipt approval、fixture dry-run、runtime write gate review、post-write verifier package、runtime verifier evidence review、報表真相、日週月報、Agent 工作量、圖表化報告、風險自動化政策、報表 runtime 啟動前閘門、no-write dry-run 證據包、fixture/readback/verifier dry-run 證據包、shadow/no-write execution evidence gate、操作類別權限模型、候選操作 dry-run 證據、任務結果稽核軌跡、matched PlayBook 學習缺口、critic / reviewer result capture gate、owner-approved result capture dry-run / readback、日週月報工作狀態總覽、runtime readback approval / implementation review、report live delivery approval package,以及 runtime readback fixture approval。 目前真相: @@ -97,7 +97,8 @@ | P2-108 report status board | 已完成,日報 / 週報 / 月報 `100%` 可見、3 個 Agent 狀態報告、3 張圖表、4 張統帥問答卡;live delivery / Telegram send / runtime work / auto optimization 全為 `0` | | P2-109 runtime readback approval package | 已完成,5 個批准包、4 個 canonical readback plan、4 條 rollback drill、4 個 Telegram failure receipt gate;runtime readback / queue / send / write 全為 `0` | | P2-110 runtime readback implementation review | 已完成,5 張 implementation review card、5 個 no-write verifier、5 個 blocker、5 個 operator action;live query / runtime execution / production write 全為 `0` | -| P2-111 report live delivery approval package | 已本地完成,5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt;scheduler / Gateway queue / Telegram send / Bot API / receipt write / AI analysis / auto optimization 全為 `0` | +| P2-111 report live delivery approval package | 已完成,5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt;scheduler / Gateway queue / Telegram send / Bot API / receipt write / AI analysis / auto optimization 全為 `0` | +| P2-112 runtime readback fixture approval | 已本地完成,5 張 fixture card、4 個 adapter contract、5 個 verifier fixture check、5 個 blocker mapping、5 個 operator action;canonical read / live query / runtime execution / Gateway queue / Telegram send / Bot API / receipt write / result capture write 全為 `0` | 這代表使用者現在可以看見「哪裡已準備好、哪裡仍未運作、被哪個 gate 阻擋、下一步要如何驗證」。但還不能宣稱三個 Agent 已經在 production runtime 主動互傳訊息或自主學習。 @@ -185,19 +186,21 @@ | `docs/evaluations/ai_agent_runtime_readback_implementation_review_2026-06-13.json` | P2-110 committed snapshot,完成度 `100%`,5 張 implementation review card、5 個 no-write verifier check、5 個 implementation blocker、5 個 operator action;live query、runtime readback execution、owner approval received 與所有 live write / send counts 全為 `0` | | `docs/schemas/ai_agent_report_live_delivery_approval_package_v1.schema.json` | P2-111 report live delivery approval package schema;強制 scheduler、Gateway queue write、Telegram send、Bot API、report receipt write、AI analysis run、中低風險 auto optimization、production write、secret read 與 destructive action 維持未授權 | | `docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json` | P2-111 committed snapshot,完成度 `100%`,5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt、5 個 operator action;scheduler、Gateway queue、Telegram send、Bot API、report receipt write、AI analysis、auto optimization 與所有 live write / send counts 全為 `0` | +| `docs/schemas/ai_agent_runtime_readback_fixture_approval_v1.schema.json` | P2-112 runtime readback fixture approval schema;強制 canonical runtime target read、live query、runtime execution、Gateway queue、Telegram send、Bot API、report receipt write、result capture write、production write、secret read 與 destructive action 維持未授權 | +| `docs/evaluations/ai_agent_runtime_readback_fixture_approval_2026-06-13.json` | P2-112 committed snapshot,完成度 `100%`,5 張 fixture approval card、4 個 adapter contract、5 個 verifier fixture check、5 個 blocker mapping 與 5 個 operator action;所有 live read / query / send / write counts 全為 `0` | | `GET /api/v1/agents/agent-critic-reviewer-result-capture` | 只讀 API;不寫 score、不寫 result capture、不寫 learning、不更新 PlayBook trust、不送 Telegram | | `apps/api/src/services/ai_agent_interaction_learning_proof.py` | 只讀 loader 與安全驗證 | | `apps/api/src/services/ai_agent_live_read_model_gate.py` | P2-403B 只讀 loader;拒絕 live DB query、Redis consumer、unsafe fields、Telegram 與 writeback | | `GET /api/v1/agents/agent-interaction-learning-proof` | 只讀 API,不啟動 worker、不碰 Redis / DB runtime、不發 Telegram | | `GET /api/v1/agents/agent-live-read-model-gate` | 只讀 API,不連 DB、不讀寫 Redis、不發 Telegram | -| governance UI | 新增證據階梯、目前真相、P2-403B live read gate、P2-403C Redis dry-run gate、P2-403D learning writeback approval package、P2-403E Telegram receipt approval package、P2-403F owner-approved learning dry-run / fixture dry-run、P2-403G runtime write gate review、P2-403H post-write verifier package、P2-403I runtime verifier evidence review、P2-403J 報表真相 / 日週月報 / Agent 工作量 / 圖表 / AI 建議、P2-108 日週月報與 Agent 工作狀態總覽、P2-403L 報表 runtime readiness、P2-403M no-write dry-run、P2-403N fixture readback、P2-404 shadow gate、P2-101 operation permission model、P2-102 candidate dry-run evidence、P2-103 task result audit trail、P2-104 matched PlayBook learning gap、P2-105 critic / reviewer result capture、P2-106 owner-approved result capture dry-run、P2-107 owner-approved result capture readback / promotion readiness、P2-109 runtime readback approval package、P2-110 runtime readback implementation review、P2-111 report live delivery approval package、Agent lane、可觀測訊號、runtime gates、前端 redaction | +| governance UI | 新增證據階梯、目前真相、P2-403B live read gate、P2-403C Redis dry-run gate、P2-403D learning writeback approval package、P2-403E Telegram receipt approval package、P2-403F owner-approved learning dry-run / fixture dry-run、P2-403G runtime write gate review、P2-403H post-write verifier package、P2-403I runtime verifier evidence review、P2-403J 報表真相 / 日週月報 / Agent 工作量 / 圖表 / AI 建議、P2-108 日週月報與 Agent 工作狀態總覽、P2-403L 報表 runtime readiness、P2-403M no-write dry-run、P2-403N fixture readback、P2-404 shadow gate、P2-101 operation permission model、P2-102 candidate dry-run evidence、P2-103 task result audit trail、P2-104 matched PlayBook learning gap、P2-105 critic / reviewer result capture、P2-106 owner-approved result capture dry-run、P2-107 owner-approved result capture readback / promotion readiness、P2-109 runtime readback approval package、P2-110 runtime readback implementation review、P2-111 report live delivery approval package、P2-112 runtime readback fixture approval、Agent lane、可觀測訊號、runtime gates、前端 redaction | ## 5. 後續優先順序 | 優先 | ID | 工作 | gate | |---:|---|---|---| -| 1 | P2-112 | runtime readback fixture approval | 以 P2-111 report live delivery approval package、P2-110 implementation review 的 adapter contract / verifier check / blocker 產生下一關 fixture-only runtime readback approval,不讀 canonical runtime target | -| 2 | P2-113 | report delivery fixture readback | 只用 fixture / no-send receipt 回放報表實發鏈,仍不排程、不寫 Gateway queue、不送 Telegram | +| 1 | P2-113 | report delivery fixture readback | 只用 fixture / no-send receipt 回放報表實發鏈,仍不排程、不寫 Gateway queue、不送 Telegram | +| 2 | P2-114 | owner-approved fixture promotion gate | P2-113 通過後才整理 owner-approved promotion package,仍不得寫 production target | ## 6. 紅線 diff --git a/docs/evaluations/ai_agent_runtime_readback_fixture_approval_2026-06-13.json b/docs/evaluations/ai_agent_runtime_readback_fixture_approval_2026-06-13.json new file mode 100644 index 000000000..044f80475 --- /dev/null +++ b/docs/evaluations/ai_agent_runtime_readback_fixture_approval_2026-06-13.json @@ -0,0 +1,425 @@ +{ + "schema_version": "ai_agent_runtime_readback_fixture_approval_v1", + "generated_at": "2026-06-13T17:45:00+08:00", + "program_status": { + "overall_completion_percent": 100, + "current_priority": "P2", + "current_task_id": "P2-112", + "next_task_id": "P2-113", + "read_only_mode": true, + "runtime_authority": "runtime_readback_fixture_approval_only_no_canonical_target_or_live_query", + "status_note": "P2-112 只建立 fixture-only runtime readback 批准包;未批准前不得讀 canonical runtime target、不得 live query、不得寫 Gateway / Telegram / Bot API / report receipt / result capture / production。" + }, + "source_refs": [ + "docs/evaluations/ai_agent_runtime_readback_implementation_review_2026-06-13.json", + "docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json", + "docs/ai/AI_AGENT_INTERACTION_LEARNING_PROOF_2026-06-11.md#5-後續優先順序", + "docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md#32-建立-report-live-delivery-approval-package" + ], + "prior_runtime_review": { + "implementation_review_schema_version": "ai_agent_runtime_readback_implementation_review_v1", + "implementation_review_card_count": 5, + "no_write_verifier_check_count": 5, + "implementation_blocker_count": 5, + "runtime_readback_execution_count": 0, + "live_query_count": 0, + "production_write_count": 0, + "readiness_note": "P2-110 已把 implementation review card、no-write verifier check 與 blocker 固定;P2-112 只把這些項目轉成 fixture-only approval,不讀 live target。" + }, + "prior_delivery_approval": { + "delivery_approval_schema_version": "ai_agent_report_live_delivery_approval_package_v1", + "delivery_approval_packet_count": 5, + "route_lock_gate_count": 4, + "payload_redaction_check_count": 5, + "dry_run_delivery_receipt_count": 4, + "telegram_send_count": 0, + "gateway_queue_write_count": 0, + "bot_api_call_count": 0, + "readiness_note": "P2-111 已建立報表實發批准包與 route lock;P2-112 仍只使用 fixture/no-send receipt 證據,不排程實發。" + }, + "fixture_approval_truth": { + "p2_110_implementation_review_loaded": true, + "p2_111_delivery_approval_loaded": true, + "fixture_approval_package_ready": true, + "adapter_contract_ready": true, + "verifier_fixture_ready": true, + "blocker_mapping_ready": true, + "owner_review_required_before_readback": true, + "canonical_runtime_target_read_enabled": false, + "live_query_enabled": false, + "runtime_readback_execution_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, + "production_write_enabled": false, + "secret_read_enabled": false, + "destructive_operation_enabled": false, + "owner_approval_received_count": 0, + "fixture_readback_execution_count": 0, + "canonical_runtime_target_read_count": 0, + "live_query_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, + "production_write_count": 0, + "truth_note": "fixture approval 已可審查;真正 runtime readback、live query 與任何寫入仍為 0。" + }, + "fixture_approval_cards": [ + { + "card_id": "report_delivery_fixture_readback", + "display_name": "報表派送 fixture readback 批准", + "owner_agent": "openclaw", + "source_task_id": "P2-111", + "status": "approval_required", + "risk_tier": "high", + "required_fixture_fields": [ + "report_type", + "route_target", + "redacted_payload_digest", + "no_send_receipt_id", + "dedupe_fingerprint" + ], + "blocked_runtime_actions": [ + "scheduler_run", + "gateway_queue_write", + "telegram_send" + ], + "operator_guidance": "先核對 P2-111 的日報 / 週報 / 月報 / 失敗限定摘要批准包是否都有 fixture payload、no-send receipt 與 SRE 戰情室 route lock。", + "owner_approval_required": true, + "fixture_only": true, + "evidence_hash": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + { + "card_id": "runtime_implementation_fixture_readback", + "display_name": "runtime implementation fixture readback 批准", + "owner_agent": "nemotron", + "source_task_id": "P2-110", + "status": "approval_required", + "risk_tier": "critical", + "required_fixture_fields": [ + "adapter_contract_id", + "expected_readback_shape", + "verifier_fixture_id", + "rollback_noop_plan", + "blocked_live_target" + ], + "blocked_runtime_actions": [ + "canonical_runtime_target_read", + "live_query", + "runtime_result_capture_write" + ], + "operator_guidance": "只允許使用 committed fixture 驗證 adapter shape,不得讀 canonical runtime target 或把 fixture approval 解讀成 live query approval。", + "owner_approval_required": true, + "fixture_only": true, + "evidence_hash": "sha256:2222222222222222222222222222222222222222222222222222222222222222" + }, + { + "card_id": "telegram_failure_receipt_fixture_readback", + "display_name": "Telegram failure receipt fixture 批准", + "owner_agent": "hermes", + "source_task_id": "P2-110", + "status": "ready_for_owner_review", + "risk_tier": "high", + "required_fixture_fields": [ + "failure_reason", + "route_lock_id", + "redaction_contract_id", + "no_send_receipt_id" + ], + "blocked_runtime_actions": [ + "telegram_send", + "bot_api_call", + "report_receipt_write" + ], + "operator_guidance": "只審 no-send fixture receipt;真正 Telegram failure receipt 要等 P2-113 後另行批准。", + "owner_approval_required": true, + "fixture_only": true, + "evidence_hash": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + }, + { + "card_id": "reviewer_queue_fixture_preview", + "display_name": "reviewer queue fixture preview 批准", + "owner_agent": "openclaw", + "source_task_id": "P2-110", + "status": "ready_for_owner_review", + "risk_tier": "medium", + "required_fixture_fields": [ + "reviewer_role", + "decision_template", + "blocked_write_summary", + "expected_owner_response" + ], + "blocked_runtime_actions": [ + "reviewer_queue_write", + "timeline_write", + "audit_db_write" + ], + "operator_guidance": "先把 reviewer 要看到的 fixture preview 固定,未批准前不建立 queue item、不寫 audit DB、不寫 timeline。", + "owner_approval_required": true, + "fixture_only": true, + "evidence_hash": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + { + "card_id": "result_capture_fixture_link", + "display_name": "result capture fixture link 批准", + "owner_agent": "nemotron", + "source_task_id": "P2-110", + "status": "blocked_by_policy", + "risk_tier": "critical", + "required_fixture_fields": [ + "critic_score_fixture", + "reviewer_score_fixture", + "promotion_gate_fixture", + "no_write_result_digest" + ], + "blocked_runtime_actions": [ + "score_write", + "result_capture_write", + "playbook_trust_write" + ], + "operator_guidance": "缺 owner acceptance record 前只能保留 fixture link;不得寫 score、result capture、PlayBook trust 或 KM。", + "owner_approval_required": true, + "fixture_only": true, + "evidence_hash": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + } + ], + "adapter_contracts": [ + { + "contract_id": "report_delivery_payload_to_fixture_readback", + "display_name": "報表 payload → fixture readback adapter", + "status": "ready", + "input_schema": "ai_agent_report_live_delivery_approval_package_v1.delivery_approval_packets", + "output_schema": "runtime_readback_fixture.packet_digest", + "required_evidence": [ + "redacted_payload_digest", + "route_lock_gate_id", + "no_send_receipt_id" + ], + "canonical_target_read_enabled": false, + "live_query_enabled": false, + "evidence_hash": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + { + "contract_id": "implementation_review_to_adapter_check", + "display_name": "implementation review → adapter check", + "status": "ready", + "input_schema": "ai_agent_runtime_readback_implementation_review_v1.implementation_review_cards", + "output_schema": "runtime_readback_fixture.adapter_contract", + "required_evidence": [ + "implementation_review_card_id", + "no_write_verifier_check_id", + "blocked_live_target" + ], + "canonical_target_read_enabled": false, + "live_query_enabled": false, + "evidence_hash": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + }, + { + "contract_id": "failure_receipt_to_fixture_verifier", + "display_name": "failure receipt → fixture verifier", + "status": "approval_required", + "input_schema": "ai_agent_runtime_readback_implementation_review_v1.telegram_failure_receipt_gate", + "output_schema": "runtime_readback_fixture.failure_receipt_digest", + "required_evidence": [ + "failure_reason", + "no_send_receipt_id", + "redaction_check_id" + ], + "canonical_target_read_enabled": false, + "live_query_enabled": false, + "evidence_hash": "sha256:8888888888888888888888888888888888888888888888888888888888888888" + }, + { + "contract_id": "result_capture_to_fixture_promotion", + "display_name": "result capture → fixture promotion gate", + "status": "blocked_by_policy", + "input_schema": "ai_agent_owner_approved_result_capture_readback_v1.promotion_readiness", + "output_schema": "runtime_readback_fixture.no_write_promotion", + "required_evidence": [ + "owner_acceptance_record", + "critic_score_fixture", + "reviewer_score_fixture" + ], + "canonical_target_read_enabled": false, + "live_query_enabled": false, + "evidence_hash": "sha256:9999999999999999999999999999999999999999999999999999999999999999" + } + ], + "verifier_fixture_checks": [ + { + "check_id": "fixture_payload_shape", + "display_name": "fixture payload shape", + "status": "ready", + "required_fixture": "redacted payload digest + schema_version + route_lock", + "failure_if_missing": "缺 payload shape 時不得推進 P2-113 fixture readback。", + "live_verifier_enabled": false, + "evidence_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + }, + { + "check_id": "no_live_target_reference", + "display_name": "no live target reference", + "status": "ready", + "required_fixture": "blocked_live_target + canonical_target_read_enabled=false", + "failure_if_missing": "若 fixture 指向 live target,必須退回 P2-112。", + "live_verifier_enabled": false, + "evidence_hash": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + }, + { + "check_id": "route_lock_fixture", + "display_name": "SRE route lock fixture", + "status": "approval_required", + "required_fixture": "AwoooI SRE 戰情室 route lock + old bot suppression", + "failure_if_missing": "缺 route lock fixture 時不得產生任何發送或 queue 草案。", + "live_verifier_enabled": false, + "evidence_hash": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + { + "check_id": "redaction_fixture", + "display_name": "redaction fixture", + "status": "ready", + "required_fixture": "no prompt / no private inference content / no raw runtime payload", + "failure_if_missing": "缺遮蔽 fixture 時不得顯示 payload 或產生讀報回執。", + "live_verifier_enabled": false, + "evidence_hash": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + }, + { + "check_id": "result_capture_no_write_fixture", + "display_name": "result capture no-write fixture", + "status": "blocked_by_policy", + "required_fixture": "score fixture + no-write digest + owner acceptance placeholder", + "failure_if_missing": "缺 owner acceptance record 前不得寫 result capture。", + "live_verifier_enabled": false, + "evidence_hash": "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + } + ], + "blocker_mappings": [ + { + "blocker_id": "canonical_runtime_target_blocked", + "display_name": "canonical runtime target blocked", + "source_blocker": "P2-110 live_query disabled", + "severity": "critical", + "blocked_action": "canonical_runtime_target_read", + "blocked_until": "owner acceptance record + P2-113 fixture readback approval", + "status": "blocked_by_policy", + "evidence_hash": "sha256:1212121212121212121212121212121212121212121212121212121212121212" + }, + { + "blocker_id": "gateway_queue_write_blocked", + "display_name": "Gateway queue write blocked", + "source_blocker": "P2-111 route lock still approval-required", + "severity": "high", + "blocked_action": "gateway_queue_write", + "blocked_until": "SRE route lock owner approval", + "status": "approval_required", + "evidence_hash": "sha256:3434343434343434343434343434343434343434343434343434343434343434" + }, + { + "blocker_id": "telegram_bot_send_blocked", + "display_name": "Telegram / Bot API send blocked", + "source_blocker": "P2-111 no-send receipt", + "severity": "high", + "blocked_action": "telegram_send_or_bot_api_call", + "blocked_until": "delivery receipt E2E approval", + "status": "approval_required", + "evidence_hash": "sha256:5656565656565656565656565656565656565656565656565656565656565656" + }, + { + "blocker_id": "report_receipt_write_blocked", + "display_name": "report receipt write blocked", + "source_blocker": "P2-111 dry-run receipt only", + "severity": "medium", + "blocked_action": "report_receipt_write", + "blocked_until": "P2-113 fixture readback pass + owner approval", + "status": "mapped", + "evidence_hash": "sha256:7878787878787878787878787878787878787878787878787878787878787878" + }, + { + "blocker_id": "result_capture_write_blocked", + "display_name": "result capture write blocked", + "source_blocker": "P2-110 implementation blocker", + "severity": "critical", + "blocked_action": "result_capture_write", + "blocked_until": "critic / reviewer acceptance record", + "status": "blocked_by_policy", + "evidence_hash": "sha256:9090909090909090909090909090909090909090909090909090909090909090" + } + ], + "operator_actions": [ + { + "action_id": "review_fixture_approval_cards", + "display_name": "審查 fixture approval cards", + "owner_agent": "openclaw", + "action_type": "review_fixture_approval", + "operator_instruction": "逐張確認 fixture approval card 是否只有 fixture 欄位、沒有 live target、沒有 send/write 權限。", + "runtime_readback_allowed": false + }, + { + "action_id": "compare_adapter_contracts", + "display_name": "比對 adapter contract", + "owner_agent": "nemotron", + "action_type": "compare_adapter_contract", + "operator_instruction": "核對 P2-110 / P2-111 輸入 schema 是否能轉成 P2-113 fixture readback,不能連線查 live target。", + "runtime_readback_allowed": false + }, + { + "action_id": "confirm_no_live_query", + "display_name": "確認 live query 仍關閉", + "owner_agent": "hermes", + "action_type": "confirm_no_live_query", + "operator_instruction": "確認 canonical target read、live query、runtime execution、Gateway、Telegram、Bot API、receipt write 都是 0 / false。", + "runtime_readback_allowed": false + }, + { + "action_id": "reject_canonical_target_scope", + "display_name": "退回 live target 混入", + "owner_agent": "nemotron", + "action_type": "reject_canonical_target", + "operator_instruction": "若任何 fixture 混入 live endpoint、secret、raw payload 或 production target,立即退回 P2-112,不進 P2-113。", + "runtime_readback_allowed": false + }, + { + "action_id": "promote_to_p2_113_fixture_readback", + "display_name": "推進 P2-113 fixture readback", + "owner_agent": "openclaw", + "action_type": "promote_to_p2_113", + "operator_instruction": "只有在 owner 接受 fixture approval cards 後,才建立 P2-113 report delivery fixture readback;仍不得實發或 live write。", + "runtime_readback_allowed": false + } + ], + "display_redaction_contract": { + "redaction_required": true, + "frontend_display_policy": "前端只顯示 fixture approval 摘要、adapter contract 名稱、verifier 狀態、blocked action 與 operator instruction;不得顯示原始提示詞、私密推理、secret、raw runtime payload 或內部協作內容。", + "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 + }, + "rollups": { + "fixture_approval_card_count": 5, + "adapter_contract_count": 4, + "verifier_fixture_check_count": 5, + "blocker_mapping_count": 5, + "operator_action_count": 5, + "approval_required_card_count": 2, + "blocked_card_count": 1, + "blocked_contract_count": 1, + "blocked_check_count": 1, + "owner_approval_received_count": 0, + "fixture_readback_execution_count": 0, + "canonical_runtime_target_read_count": 0, + "live_query_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, + "production_write_count": 0, + "secret_read_count": 0, + "destructive_operation_count": 0 + } +} diff --git a/docs/schemas/ai_agent_runtime_readback_fixture_approval_v1.schema.json b/docs/schemas/ai_agent_runtime_readback_fixture_approval_v1.schema.json new file mode 100644 index 000000000..60f87ce29 --- /dev/null +++ b/docs/schemas/ai_agent_runtime_readback_fixture_approval_v1.schema.json @@ -0,0 +1,506 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://awoooi.wooo.work/schemas/ai_agent_runtime_readback_fixture_approval_v1.schema.json", + "title": "AI Agent Runtime Readback Fixture Approval v1", + "type": "object", + "additionalProperties": false, + "required": [ + "schema_version", + "generated_at", + "program_status", + "source_refs", + "prior_runtime_review", + "prior_delivery_approval", + "fixture_approval_truth", + "fixture_approval_cards", + "adapter_contracts", + "verifier_fixture_checks", + "blocker_mappings", + "operator_actions", + "display_redaction_contract", + "rollups" + ], + "properties": { + "schema_version": { + "const": "ai_agent_runtime_readback_fixture_approval_v1" + }, + "generated_at": { + "type": "string", + "minLength": 1 + }, + "program_status": { + "type": "object", + "additionalProperties": false, + "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-112" + }, + "next_task_id": { + "const": "P2-113" + }, + "read_only_mode": { + "const": true + }, + "runtime_authority": { + "const": "runtime_readback_fixture_approval_only_no_canonical_target_or_live_query" + }, + "status_note": { + "type": "string", + "minLength": 1 + } + } + }, + "source_refs": { + "$ref": "#/$defs/string_array" + }, + "prior_runtime_review": { + "$ref": "#/$defs/prior_runtime_review" + }, + "prior_delivery_approval": { + "$ref": "#/$defs/prior_delivery_approval" + }, + "fixture_approval_truth": { + "$ref": "#/$defs/fixture_approval_truth" + }, + "fixture_approval_cards": { + "type": "array", + "minItems": 5, + "items": { + "$ref": "#/$defs/fixture_approval_card" + } + }, + "adapter_contracts": { + "type": "array", + "minItems": 4, + "items": { + "$ref": "#/$defs/adapter_contract" + } + }, + "verifier_fixture_checks": { + "type": "array", + "minItems": 5, + "items": { + "$ref": "#/$defs/verifier_fixture_check" + } + }, + "blocker_mappings": { + "type": "array", + "minItems": 5, + "items": { + "$ref": "#/$defs/blocker_mapping" + } + }, + "operator_actions": { + "type": "array", + "minItems": 5, + "items": { + "$ref": "#/$defs/operator_action" + } + }, + "display_redaction_contract": { + "$ref": "#/$defs/display_redaction_contract" + }, + "rollups": { + "$ref": "#/$defs/rollups" + } + }, + "$defs": { + "string_array": { + "type": "array", + "minItems": 1, + "items": { + "type": "string", + "minLength": 1 + } + }, + "redacted_sha256": { + "type": "string", + "pattern": "^sha256:[0-9a-f]{64}$" + }, + "owner_agent": { + "enum": [ + "openclaw", + "hermes", + "nemotron" + ] + }, + "risk_tier": { + "enum": [ + "medium", + "high", + "critical" + ] + }, + "prior_runtime_review": { + "type": "object", + "additionalProperties": false, + "required": [ + "implementation_review_schema_version", + "implementation_review_card_count", + "no_write_verifier_check_count", + "implementation_blocker_count", + "runtime_readback_execution_count", + "live_query_count", + "production_write_count", + "readiness_note" + ], + "properties": { + "implementation_review_schema_version": { + "const": "ai_agent_runtime_readback_implementation_review_v1" + }, + "implementation_review_card_count": { + "const": 5 + }, + "no_write_verifier_check_count": { + "const": 5 + }, + "implementation_blocker_count": { + "const": 5 + }, + "runtime_readback_execution_count": { + "const": 0 + }, + "live_query_count": { + "const": 0 + }, + "production_write_count": { + "const": 0 + }, + "readiness_note": { + "type": "string", + "minLength": 1 + } + } + }, + "prior_delivery_approval": { + "type": "object", + "additionalProperties": false, + "required": [ + "delivery_approval_schema_version", + "delivery_approval_packet_count", + "route_lock_gate_count", + "payload_redaction_check_count", + "dry_run_delivery_receipt_count", + "telegram_send_count", + "gateway_queue_write_count", + "bot_api_call_count", + "readiness_note" + ], + "properties": { + "delivery_approval_schema_version": { + "const": "ai_agent_report_live_delivery_approval_package_v1" + }, + "delivery_approval_packet_count": { + "const": 5 + }, + "route_lock_gate_count": { + "const": 4 + }, + "payload_redaction_check_count": { + "const": 5 + }, + "dry_run_delivery_receipt_count": { + "const": 4 + }, + "telegram_send_count": { + "const": 0 + }, + "gateway_queue_write_count": { + "const": 0 + }, + "bot_api_call_count": { + "const": 0 + }, + "readiness_note": { + "type": "string", + "minLength": 1 + } + } + }, + "fixture_approval_truth": { + "type": "object", + "additionalProperties": false, + "required": [ + "p2_110_implementation_review_loaded", + "p2_111_delivery_approval_loaded", + "fixture_approval_package_ready", + "adapter_contract_ready", + "verifier_fixture_ready", + "blocker_mapping_ready", + "owner_review_required_before_readback", + "canonical_runtime_target_read_enabled", + "live_query_enabled", + "runtime_readback_execution_enabled", + "gateway_queue_write_enabled", + "telegram_send_enabled", + "bot_api_call_enabled", + "report_receipt_write_enabled", + "result_capture_write_enabled", + "production_write_enabled", + "secret_read_enabled", + "destructive_operation_enabled", + "owner_approval_received_count", + "fixture_readback_execution_count", + "canonical_runtime_target_read_count", + "live_query_count", + "gateway_queue_write_count", + "telegram_send_count", + "bot_api_call_count", + "report_receipt_write_count", + "result_capture_write_count", + "production_write_count", + "truth_note" + ], + "properties": { + "p2_110_implementation_review_loaded": { "const": true }, + "p2_111_delivery_approval_loaded": { "const": true }, + "fixture_approval_package_ready": { "const": true }, + "adapter_contract_ready": { "const": true }, + "verifier_fixture_ready": { "const": true }, + "blocker_mapping_ready": { "const": true }, + "owner_review_required_before_readback": { "const": true }, + "canonical_runtime_target_read_enabled": { "const": false }, + "live_query_enabled": { "const": false }, + "runtime_readback_execution_enabled": { "const": false }, + "gateway_queue_write_enabled": { "const": false }, + "telegram_send_enabled": { "const": false }, + "bot_api_call_enabled": { "const": false }, + "report_receipt_write_enabled": { "const": false }, + "result_capture_write_enabled": { "const": false }, + "production_write_enabled": { "const": false }, + "secret_read_enabled": { "const": false }, + "destructive_operation_enabled": { "const": false }, + "owner_approval_received_count": { "const": 0 }, + "fixture_readback_execution_count": { "const": 0 }, + "canonical_runtime_target_read_count": { "const": 0 }, + "live_query_count": { "const": 0 }, + "gateway_queue_write_count": { "const": 0 }, + "telegram_send_count": { "const": 0 }, + "bot_api_call_count": { "const": 0 }, + "report_receipt_write_count": { "const": 0 }, + "result_capture_write_count": { "const": 0 }, + "production_write_count": { "const": 0 }, + "truth_note": { "type": "string", "minLength": 1 } + } + }, + "fixture_approval_card": { + "type": "object", + "additionalProperties": false, + "required": [ + "card_id", + "display_name", + "owner_agent", + "source_task_id", + "status", + "risk_tier", + "required_fixture_fields", + "blocked_runtime_actions", + "operator_guidance", + "owner_approval_required", + "fixture_only", + "evidence_hash" + ], + "properties": { + "card_id": { "type": "string", "minLength": 1 }, + "display_name": { "type": "string", "minLength": 1 }, + "owner_agent": { "$ref": "#/$defs/owner_agent" }, + "source_task_id": { "enum": ["P2-110", "P2-111"] }, + "status": { "enum": ["approval_required", "ready_for_owner_review", "blocked_by_policy"] }, + "risk_tier": { "$ref": "#/$defs/risk_tier" }, + "required_fixture_fields": { "$ref": "#/$defs/string_array" }, + "blocked_runtime_actions": { "$ref": "#/$defs/string_array" }, + "operator_guidance": { "type": "string", "minLength": 1 }, + "owner_approval_required": { "const": true }, + "fixture_only": { "const": true }, + "evidence_hash": { "$ref": "#/$defs/redacted_sha256" } + } + }, + "adapter_contract": { + "type": "object", + "additionalProperties": false, + "required": [ + "contract_id", + "display_name", + "status", + "input_schema", + "output_schema", + "required_evidence", + "canonical_target_read_enabled", + "live_query_enabled", + "evidence_hash" + ], + "properties": { + "contract_id": { "type": "string", "minLength": 1 }, + "display_name": { "type": "string", "minLength": 1 }, + "status": { "enum": ["ready", "approval_required", "blocked_by_policy"] }, + "input_schema": { "type": "string", "minLength": 1 }, + "output_schema": { "type": "string", "minLength": 1 }, + "required_evidence": { "$ref": "#/$defs/string_array" }, + "canonical_target_read_enabled": { "const": false }, + "live_query_enabled": { "const": false }, + "evidence_hash": { "$ref": "#/$defs/redacted_sha256" } + } + }, + "verifier_fixture_check": { + "type": "object", + "additionalProperties": false, + "required": [ + "check_id", + "display_name", + "status", + "required_fixture", + "failure_if_missing", + "live_verifier_enabled", + "evidence_hash" + ], + "properties": { + "check_id": { "type": "string", "minLength": 1 }, + "display_name": { "type": "string", "minLength": 1 }, + "status": { "enum": ["ready", "approval_required", "blocked_by_policy"] }, + "required_fixture": { "type": "string", "minLength": 1 }, + "failure_if_missing": { "type": "string", "minLength": 1 }, + "live_verifier_enabled": { "const": false }, + "evidence_hash": { "$ref": "#/$defs/redacted_sha256" } + } + }, + "blocker_mapping": { + "type": "object", + "additionalProperties": false, + "required": [ + "blocker_id", + "display_name", + "source_blocker", + "severity", + "blocked_action", + "blocked_until", + "status", + "evidence_hash" + ], + "properties": { + "blocker_id": { "type": "string", "minLength": 1 }, + "display_name": { "type": "string", "minLength": 1 }, + "source_blocker": { "type": "string", "minLength": 1 }, + "severity": { "enum": ["medium", "high", "critical"] }, + "blocked_action": { "type": "string", "minLength": 1 }, + "blocked_until": { "type": "string", "minLength": 1 }, + "status": { "enum": ["mapped", "approval_required", "blocked_by_policy"] }, + "evidence_hash": { "$ref": "#/$defs/redacted_sha256" } + } + }, + "operator_action": { + "type": "object", + "additionalProperties": false, + "required": [ + "action_id", + "display_name", + "owner_agent", + "action_type", + "operator_instruction", + "runtime_readback_allowed" + ], + "properties": { + "action_id": { "type": "string", "minLength": 1 }, + "display_name": { "type": "string", "minLength": 1 }, + "owner_agent": { "$ref": "#/$defs/owner_agent" }, + "action_type": { + "enum": [ + "review_fixture_approval", + "compare_adapter_contract", + "confirm_no_live_query", + "reject_canonical_target", + "promote_to_p2_113" + ] + }, + "operator_instruction": { "type": "string", "minLength": 1 }, + "runtime_readback_allowed": { "const": false } + } + }, + "display_redaction_contract": { + "type": "object", + "additionalProperties": false, + "required": [ + "redaction_required", + "frontend_display_policy", + "raw_prompt_display_allowed", + "private_reasoning_display_allowed", + "secret_value_display_allowed", + "raw_runtime_payload_display_allowed", + "internal_collaboration_content_display_allowed" + ], + "properties": { + "redaction_required": { "const": true }, + "frontend_display_policy": { "type": "string", "minLength": 1 }, + "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 } + } + }, + "rollups": { + "type": "object", + "additionalProperties": false, + "required": [ + "fixture_approval_card_count", + "adapter_contract_count", + "verifier_fixture_check_count", + "blocker_mapping_count", + "operator_action_count", + "approval_required_card_count", + "blocked_card_count", + "blocked_contract_count", + "blocked_check_count", + "owner_approval_received_count", + "fixture_readback_execution_count", + "canonical_runtime_target_read_count", + "live_query_count", + "gateway_queue_write_count", + "telegram_send_count", + "bot_api_call_count", + "report_receipt_write_count", + "result_capture_write_count", + "production_write_count", + "secret_read_count", + "destructive_operation_count" + ], + "properties": { + "fixture_approval_card_count": { "const": 5 }, + "adapter_contract_count": { "const": 4 }, + "verifier_fixture_check_count": { "const": 5 }, + "blocker_mapping_count": { "const": 5 }, + "operator_action_count": { "const": 5 }, + "approval_required_card_count": { "type": "integer", "minimum": 0 }, + "blocked_card_count": { "type": "integer", "minimum": 0 }, + "blocked_contract_count": { "type": "integer", "minimum": 0 }, + "blocked_check_count": { "type": "integer", "minimum": 0 }, + "owner_approval_received_count": { "const": 0 }, + "fixture_readback_execution_count": { "const": 0 }, + "canonical_runtime_target_read_count": { "const": 0 }, + "live_query_count": { "const": 0 }, + "gateway_queue_write_count": { "const": 0 }, + "telegram_send_count": { "const": 0 }, + "bot_api_call_count": { "const": 0 }, + "report_receipt_write_count": { "const": 0 }, + "result_capture_write_count": { "const": 0 }, + "production_write_count": { "const": 0 }, + "secret_read_count": { "const": 0 }, + "destructive_operation_count": { "const": 0 } + } + } + } +} diff --git a/docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md b/docs/superpowers/specs/2026-04-15-MASTER-ai-autonomous-flywheel-v2.md index 6efa061ba..1fff2ca96 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 @@ -649,6 +649,7 @@ Alert / Sentry / SigNoz / Gitea / Market Watch / Operator | `docs/evaluations/ai_agent_runtime_readback_approval_package_2026-06-13.json` + `GET /api/v1/agents/agent-runtime-readback-approval-package` | P2-109 runtime readback approval package;承接 P2-107 readback / promotion readiness 與 P2-108 report status board,建立 5 個批准包、4 個 canonical readback plan、4 條 rollback drill、4 個 Telegram failure receipt gate 與 5 個 operator action;canonical runtime readback、runtime readback execution、owner approval received、reviewer queue write、rollback work item write、Gateway queue、Telegram failure receipt、Bot API、score / result capture / learning / trust / production write、secret read 與 destructive action 全部 `0 / false`,下一步 P2-110 | | `docs/evaluations/ai_agent_runtime_readback_implementation_review_2026-06-13.json` + `GET /api/v1/agents/agent-runtime-readback-implementation-review` | P2-110 runtime readback implementation review;承接 P2-109 approval package,建立 5 張 implementation review card、5 個 no-write verifier check、5 個 implementation blocker 與 5 個 operator action;canonical runtime readback、live query、runtime readback execution、owner approval received、reviewer queue write、rollback work item write、Gateway queue、Telegram failure receipt、Bot API、score / result capture / learning / trust / production write、secret read 與 destructive action 全部 `0 / false`,下一步 P2-111 | | `docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json` + `GET /api/v1/agents/agent-report-live-delivery-approval-package` | P2-111 report live delivery approval package;承接 P2-108 report status board、P2-109 Telegram failure receipt gate 與 P2-110 implementation review,建立日報 / 週報 / 月報 / 失敗限定摘要 / 讀報回執 5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt 與 5 個 operator action;scheduler、Gateway queue、Telegram send、Bot API、report receipt write、AI analysis run、中低風險 auto optimization、production write、secret read 與 destructive action 全部 `0 / false`,下一步 P2-112 | +| `docs/evaluations/ai_agent_runtime_readback_fixture_approval_2026-06-13.json` + `GET /api/v1/agents/agent-runtime-readback-fixture-approval` | P2-112 runtime readback fixture approval;承接 P2-110 implementation review 與 P2-111 report live delivery approval package,建立 5 張 fixture approval card、4 個 adapter contract、5 個 verifier fixture check、5 個 blocker mapping 與 5 個 operator action;canonical runtime target read、live query、runtime readback execution、Gateway queue、Telegram send、Bot API、report receipt write、result capture write、production write、secret read 與 destructive action 全部 `0 / false`,下一步 P2-113 | | `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 主動營運委派與版本生命週期契約 @@ -749,6 +750,7 @@ Repo / registry / release notes / K8s / host / observability / backup evidence 30. 建立 runtime readback approval package。✅ P2-109 已完成;批准包 `5`、canonical readback plan `4`、rollback drill `4`、Telegram failure receipt gate `4`、operator action `5`,canonical runtime readback、runtime readback execution、owner approval received、reviewer queue write、rollback work item write、Gateway / Telegram failure receipt / Bot API / production write 仍為 `0 / false`。下一步 P2-110。 31. 建立 runtime readback implementation review。✅ P2-110 已完成並正式驗證;implementation review card `5`、no-write verifier check `5`、implementation blocker `5`、operator action `5`,approval required card `2`、critical blocker `2`;canonical runtime readback、live query、runtime readback execution、owner approval received、reviewer queue write、rollback work item write、Gateway / Telegram failure receipt / Bot API / production write 仍為 `0 / false`。下一步 P2-111。 32. 建立 report live delivery approval package。✅ P2-111 已完成並正式驗證;delivery approval packet `5`、route lock gate `4`、payload redaction check `5`、no-send receipt `4`、operator action `5`,approval required packet `3`、blocked total `3`;scheduler、Gateway queue write、Telegram send、Bot API、report receipt write、AI analysis run、中低風險 auto optimization、production write 仍為 `0 / false`。下一步 P2-112。 +33. 建立 runtime readback fixture approval。✅ P2-112 已本地完成;fixture approval card `5`、adapter contract `4`、verifier fixture check `5`、blocker mapping `5`、operator action `5`,approval required card `2`、blocked total `3`;canonical runtime target read、live query、runtime readback execution、Gateway queue write、Telegram send、Bot API、report receipt write、result capture write、production write 仍為 `0 / false`。下一步 P2-113。 #### 3.2.1d 2026-06-11 Agent 互動、學習與成長證據面 @@ -795,6 +797,8 @@ Repo / registry / release notes / K8s / host / observability / backup evidence | `docs/evaluations/ai_agent_runtime_readback_implementation_review_2026-06-13.json` + `GET /api/v1/agents/agent-runtime-readback-implementation-review` | P2-110 committed snapshot;5 張 implementation review card、5 個 no-write verifier check、5 個 implementation blocker、5 個 operator action;不讀 canonical runtime target、不做 live query、不寫 reviewer queue、不寫 rollback work item、不送 Telegram、不呼叫 Bot API、不寫 production target、不讀 secret、不執行 destructive action | | `docs/schemas/ai_agent_report_live_delivery_approval_package_v1.schema.json` | P2-111 report live delivery approval package schema;強制 scheduler、Gateway queue write、Telegram send、Bot API、report receipt write、AI analysis run、中低風險 auto optimization、production write、secret read 與 destructive action 全部維持 `0 / false` | | `docs/evaluations/ai_agent_report_live_delivery_approval_package_2026-06-13.json` + `GET /api/v1/agents/agent-report-live-delivery-approval-package` | P2-111 committed snapshot;5 個實發批准包、4 個 route lock gate、5 個 payload redaction check、4 個 no-send receipt、5 個 operator action;不排程、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不啟動 AI analysis、不做自動優化、不寫 production target、不讀 secret、不執行 destructive action | +| `docs/schemas/ai_agent_runtime_readback_fixture_approval_v1.schema.json` | P2-112 runtime readback fixture approval schema;強制 canonical runtime target read、live query、runtime readback execution、Gateway queue、Telegram send、Bot API、report receipt write、result capture write、production write、secret read 與 destructive action 全部維持 `0 / false` | +| `docs/evaluations/ai_agent_runtime_readback_fixture_approval_2026-06-13.json` + `GET /api/v1/agents/agent-runtime-readback-fixture-approval` | P2-112 committed snapshot;5 張 fixture approval card、4 個 adapter contract、5 個 verifier fixture check、5 個 blocker mapping 與 5 個 operator action;不讀 canonical runtime target、不做 live query、不執行 runtime readback、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不寫 result capture、不寫 production target、不讀 secret、不執行 destructive action | | `apps/api/src/services/ai_agent_interaction_learning_proof.py` | 只讀 loader;強制 live flags / DB / Redis / Telegram / transcript / 私有推理全部關閉 | | `GET /api/v1/agents/agent-interaction-learning-proof` | 治理 API;只回傳證據面,不啟動 worker、不碰 live DB/Redis、不發 Telegram | | `docs/schemas/ai_agent_live_read_model_gate_v1.schema.json` | P2-403B live read model gate schema;強制 DB / Redis / worker / Telegram / learning writeback 仍需批准 | @@ -1991,6 +1995,14 @@ Phase 6 完成後 - 政策裁決:P2-106 只允許在統帥批准後產生 no-write preview 與 verifier fixture;不得把批准包、score fixture 或 dry-run template 解讀成 runtime score / result capture / learning 已寫入。 - 本波仍不寫 score、不寫 result capture、不寫 learning、不更新 PlayBook trust、不寫 KM、不 runtime append LOGBOOK、不寫 audit DB、不寫 timeline、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不啟動 runtime worker、不讀 secret、不執行 destructive action、不回傳內部協作內容;已由 P2-107 承接。 +### 2026-06-13 17:01 (台北) — §3.2 / §5 — 本地完成 P2-112 runtime readback fixture approval — 把實發批准與實作審查轉成 fixture-only readback gate + +- 新增 `ai_agent_runtime_readback_fixture_approval_v1` schema / committed snapshot / loader / API / 測試,承接 P2-110 implementation review 與 P2-111 report live delivery approval package,定義 5 張 fixture approval card、4 個 adapter contract、5 個 verifier fixture check、5 個 blocker mapping 與 5 個 operator action。 +- `apps/web/src/app/[locale]/governance/tabs/automation-inventory-tab.tsx` 接入 `GET /api/v1/agents/agent-runtime-readback-fixture-approval`,治理頁顯示 P2-112 進度 `100%`、fixture 卡 `5`、adapter contract `4`、verifier fixture `5`、阻塞映射 `5`、操作選項 `5`、需批准 `2`、阻擋總數 `3`、owner approval received `0`、fixture readback execution `0`、canonical runtime target read `0`、live query `0`、Gateway queue `0`、Telegram send `0`、Bot API `0`、report receipt write `0`、result capture write `0` 與 live writes `0`。 +- 本地驗證:P2-111 / P2-112 API/service regression `15 passed`、JSON parse、py_compile、i18n mirror `10946` leaves diff `0`、web typecheck、source-control owner response guard、security mirror progress guard、doc secret sanity 與 `git diff --check` 通過。 +- 政策裁決:P2-112 只允許 fixture approval card、adapter contract、verifier fixture、blocker mapping 與 operator action 可視化;不得把 fixture package 解讀成 canonical runtime read、live query、runtime execution、Gateway queue write、Telegram send、Bot API、report receipt write、result capture write 或 production write 已啟用。 +- 本波仍不讀 canonical runtime target、不做 live query、不執行 runtime readback、不寫 Gateway queue、不送 Telegram、不呼叫 Bot API、不寫 report receipt、不寫 result capture、不寫 production target、不讀 secret、不執行 destructive action、不回傳內部協作內容;下一步 P2-113。 + ### 2026-06-13 15:12 (台北) — §3.2 / §5 — 完成 P2-109 runtime readback approval package — 把下一關 runtime readback 固定成批准包 - 新增 `ai_agent_runtime_readback_approval_package_v1` schema / committed snapshot / loader / API / 測試,承接 P2-107 的 readback digest、promotion review、failure lane、reviewer queue preview 與 P2-108 report status board,定義 5 個批准包、4 個 canonical readback plan、4 條 rollback drill、4 個 Telegram failure receipt gate 與 5 個 operator action。