diff --git a/apps/api/src/services/awooop_ansible_audit_service.py b/apps/api/src/services/awooop_ansible_audit_service.py
index b748fd76..06617cc4 100644
--- a/apps/api/src/services/awooop_ansible_audit_service.py
+++ b/apps/api/src/services/awooop_ansible_audit_service.py
@@ -217,6 +217,18 @@ def _int_or_none(value: Any) -> int | None:
return None
+def _is_controlled_apply_record(row: dict[str, Any]) -> bool:
+ if not row:
+ return False
+ if row.get("approval_source"):
+ return True
+ if str(row.get("execution_mode") or "").strip().lower() == "controlled_apply":
+ return True
+ if "controlled_apply" in _tags(row):
+ return True
+ return str(row.get("actor") or "").strip().lower() == "ansible_controlled_apply_worker"
+
+
def _is_ansible_operation(row: dict[str, Any]) -> bool:
operation_type = str(_get(row, "operation_type") or "").lower()
if operation_type in ANSIBLE_OPERATION_TYPES:
@@ -341,7 +353,7 @@ def summarize_ansible_execution(records: list[dict[str, Any]]) -> dict[str, Any]
"pending_check_mode_total": pending_check_mode_total,
"applied_success_total": applied_success_total,
"applied": applied_success_total > 0,
- "controlled_apply": bool(latest_apply) and bool(approval_source),
+ "controlled_apply": bool(latest_apply) and _is_controlled_apply_record(latest_apply),
"latest_operation_type": focused.get("operation_type"),
"latest_status": focused.get("status"),
"latest_catalog_id": focused.get("catalog_id"),
diff --git a/apps/api/src/services/awooop_ansible_check_mode_service.py b/apps/api/src/services/awooop_ansible_check_mode_service.py
index d44b4c69..a88679b8 100644
--- a/apps/api/src/services/awooop_ansible_check_mode_service.py
+++ b/apps/api/src/services/awooop_ansible_check_mode_service.py
@@ -805,6 +805,41 @@ async def _record_post_apply_verifier_and_learning(
return status
+async def _send_controlled_apply_telegram_receipt(
+ claim: AnsibleCheckModeClaim,
+ result: AnsibleRunResult,
+ *,
+ apply_op_id: str,
+ writeback: dict[str, bool],
+ project_id: str,
+) -> bool:
+ try:
+ from src.services.telegram_gateway import get_telegram_gateway
+
+ response = await get_telegram_gateway().send_controlled_apply_result_receipt(
+ incident_id=claim.incident_id,
+ catalog_id=claim.catalog_id,
+ apply_op_id=apply_op_id,
+ playbook_path=claim.apply_playbook_path,
+ verification_result=_post_apply_verification_result(result),
+ returncode=result.returncode,
+ duration_ms=result.duration_ms,
+ verifier_written=bool(writeback.get("verification")),
+ learning_written=bool(writeback.get("learning")),
+ project_id=project_id,
+ )
+ return bool(response)
+ except Exception as exc:
+ logger.warning(
+ "ansible_controlled_apply_telegram_receipt_failed",
+ incident_id=claim.incident_id,
+ catalog_id=claim.catalog_id,
+ apply_op_id=apply_op_id,
+ error=str(exc),
+ )
+ return False
+
+
async def backfill_missing_auto_repair_execution_receipts_once(
*,
project_id: str = "awoooi",
@@ -1322,6 +1357,13 @@ async def run_controlled_apply_for_claim(
apply_op_id=apply_op_id,
project_id=project_id,
)
+ telegram_receipt_sent = await _send_controlled_apply_telegram_receipt(
+ claim,
+ result,
+ apply_op_id=apply_op_id,
+ writeback=writeback,
+ project_id=project_id,
+ )
logger.info(
"ansible_controlled_apply_completed",
@@ -1335,6 +1377,7 @@ async def run_controlled_apply_for_claim(
auto_repair_receipt_written=receipt_written,
post_apply_verification_written=writeback.get("verification"),
post_apply_learning_written=writeback.get("learning"),
+ telegram_receipt_sent=telegram_receipt_sent,
)
return result
diff --git a/apps/api/src/services/iwooos_wazuh_manager_registry_reviewer_validation.py b/apps/api/src/services/iwooos_wazuh_manager_registry_reviewer_validation.py
index 934413fb..9ba655c8 100644
--- a/apps/api/src/services/iwooos_wazuh_manager_registry_reviewer_validation.py
+++ b/apps/api/src/services/iwooos_wazuh_manager_registry_reviewer_validation.py
@@ -148,7 +148,7 @@ def load_latest_iwooos_wazuh_manager_registry_reviewer_validation(
"schema_version": "iwooos_wazuh_manager_registry_reviewer_validation_readback_v1",
"source_schema_version": snapshot["schema_version"],
"status": snapshot.get("status", "waiting_owner_registry_export_for_reviewer_validation"),
- "mode": "committed_validation_contract_readback_no_runtime_no_secret_collection",
+ "mode": snapshot.get("mode", "committed_validation_contract_readback_no_runtime_no_secret_collection"),
"source_refs": [
f"docs/security/{_SNAPSHOT_FILE}",
"scripts/security/wazuh-manager-registry-reviewer-validation.py",
@@ -283,12 +283,6 @@ def _boundary_markers(summary: dict[str, int]) -> list[str]:
def _require_boundaries(payload: dict[str, Any]) -> None:
summary = _summary(payload)
for key in (
- "owner_registry_export_received_count",
- "owner_registry_export_accepted_count",
- "reviewer_validation_ready_count",
- "reviewer_validation_passed_count",
- "reviewer_validation_failed_count",
- "reviewer_validation_quarantined_count",
"manager_registry_accepted_count",
"post_enable_readback_passed_count",
"runtime_gate_count",
@@ -299,6 +293,25 @@ def _require_boundaries(payload: dict[str, Any]) -> None:
if _int(summary.get(key)) != 0:
raise ValueError(f"Wazuh manager registry reviewer validation summary.{key} 必須維持 0")
+ received = _int(summary.get("owner_registry_export_received_count"))
+ accepted = _int(summary.get("owner_registry_export_accepted_count"))
+ ready = _int(summary.get("reviewer_validation_ready_count"))
+ passed = _int(summary.get("reviewer_validation_passed_count"))
+ failed = _int(summary.get("reviewer_validation_failed_count"))
+ quarantined = _int(summary.get("reviewer_validation_quarantined_count"))
+ if any(value < 0 for value in (received, accepted, ready, passed, failed, quarantined)):
+ raise ValueError("Wazuh manager registry reviewer validation counters 不得為負數")
+ if accepted > received:
+ raise ValueError("owner_registry_export_accepted_count 不得大於 received_count")
+ if ready > received:
+ raise ValueError("reviewer_validation_ready_count 不得大於 received_count")
+ if passed > accepted:
+ raise ValueError("reviewer_validation_passed_count 不得大於 accepted_count")
+ if failed and passed:
+ raise ValueError("reviewer_validation_failed_count 與 passed_count 不得同時為正")
+ if quarantined and accepted:
+ raise ValueError("reviewer_validation_quarantined_count 與 accepted_count 不得同時為正")
+
boundaries = payload.get("execution_boundaries")
if not isinstance(boundaries, dict):
raise ValueError("Wazuh manager registry reviewer validation execution_boundaries 缺失")
diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py
index a8a7aad9..fa0af992 100644
--- a/apps/api/src/services/telegram_gateway.py
+++ b/apps/api/src/services/telegram_gateway.py
@@ -9182,6 +9182,107 @@ class TelegramGateway:
}
return await self._send_request("sendMessage", payload)
+ async def send_controlled_apply_result_receipt(
+ self,
+ *,
+ incident_id: str,
+ catalog_id: str,
+ apply_op_id: str,
+ playbook_path: str,
+ verification_result: str,
+ returncode: int,
+ duration_ms: int,
+ verifier_written: bool,
+ learning_written: bool,
+ project_id: str = "awoooi",
+ ) -> dict:
+ """Send and mirror the AI Agent controlled-apply result receipt."""
+
+ if not self.alert_chat_id:
+ logger.warning(
+ "controlled_apply_result_receipt_skipped_no_chat",
+ incident_id=incident_id,
+ apply_op_id=apply_op_id,
+ )
+ return {}
+
+ success = verification_result == "success" and returncode == 0
+ next_step = (
+ "monitor_for_regression"
+ if success
+ else "queue_ai_rollback_or_playbook_repair"
+ )
+ title = (
+ "CONTROLLED APPLY RESULT|AI Agent 受控執行完成"
+ if success
+ else "CONTROLLED APPLY RESULT|AI Agent 受控執行待修復"
+ )
+ truth_chain: dict[str, object] | None = None
+ try:
+ from src.services.awooop_truth_chain_service import fetch_truth_chain
+
+ truth_chain = await fetch_truth_chain(
+ source_id=incident_id,
+ project_id=project_id or "awoooi",
+ )
+ except Exception as exc:
+ logger.warning(
+ "controlled_apply_result_truth_chain_snapshot_failed",
+ incident_id=incident_id,
+ apply_op_id=apply_op_id,
+ error=str(exc),
+ )
+
+ status_snapshot = _callback_reply_awooop_status_chain_snapshot(
+ incident_id=incident_id,
+ truth_chain=truth_chain,
+ )
+ source_extra = _callback_reply_source_envelope_extra(
+ incident_id=incident_id,
+ failure_context="controlled_apply_result",
+ status="callback_reply_sent",
+ chunk_index=0,
+ chunk_count=1,
+ callback_action="controlled_apply_result",
+ parse_mode="HTML",
+ awooop_status_chain=status_snapshot,
+ )
+ lines = [
+ f"{html.escape(title)}",
+ f"Incident: {html.escape(str(incident_id))}",
+ f"Catalog: {html.escape(str(catalog_id or '--'))}",
+ f"Apply op: {html.escape(str(apply_op_id or '')[:8])}",
+ f"PlayBook: {html.escape(str(playbook_path or '--'))}",
+ (
+ "Result: "
+ f"{html.escape(str(verification_result or 'missing'))} "
+ f"/ rc {html.escape(str(returncode))} "
+ f"/ {html.escape(str(duration_ms))}ms"
+ ),
+ (
+ "Receipts: verifier "
+ f"{html.escape(_bool_code(verifier_written))} / KM "
+ f"{html.escape(_bool_code(learning_written))}"
+ ),
+ f"Next: {html.escape(next_step)}",
+ f"Runs: {html.escape(incident_runs_url(incident_id, project_id=project_id or 'awoooi'))}",
+ ]
+ payload: dict = {
+ "chat_id": self.alert_chat_id,
+ "text": "\n".join(lines)[:4096],
+ "parse_mode": "HTML",
+ "disable_web_page_preview": True,
+ }
+ reply_markup = incident_truth_chain_reply_markup(
+ incident_id,
+ project_id=project_id or "awoooi",
+ )
+ if reply_markup:
+ payload["reply_markup"] = reply_markup
+ if source_extra:
+ payload[_AWOOOP_SOURCE_ENVELOPE_EXTRA_KEY] = source_extra
+ return await self._send_request("sendMessage", payload)
+
# =========================================================================
# 2026-04-24 Claude Sonnet 4.6 (ADR-095 WS4): Hermes NL 回覆
# =========================================================================
diff --git a/apps/api/tests/test_ai_agent_autonomous_runtime_control.py b/apps/api/tests/test_ai_agent_autonomous_runtime_control.py
index 7a41b887..ca6e679f 100644
--- a/apps/api/tests/test_ai_agent_autonomous_runtime_control.py
+++ b/apps/api/tests/test_ai_agent_autonomous_runtime_control.py
@@ -14,7 +14,7 @@ def test_ai_agent_autonomous_runtime_control_uses_current_owner_directive():
"p2_416_d1n_autonomous_runtime_control_prod_readback_v2"
)
assert data["program_status"]["deploy_attempt_note"] == (
- "cd_3660_failed_host_pressure_guard_retry"
+ "cd_3673_retry_after_host_pressure_gate_fix"
)
assert data["program_status"]["legacy_no_send_no_live_rules_overridden"] is True
assert data["program_status"]["implementation_completion_percent"] == 88
diff --git a/apps/api/tests/test_ai_agent_autonomous_runtime_control_api.py b/apps/api/tests/test_ai_agent_autonomous_runtime_control_api.py
index 8e24d768..35d34342 100644
--- a/apps/api/tests/test_ai_agent_autonomous_runtime_control_api.py
+++ b/apps/api/tests/test_ai_agent_autonomous_runtime_control_api.py
@@ -55,7 +55,7 @@ def test_get_ai_agent_autonomous_runtime_control_api():
"p2_416_d1n_autonomous_runtime_control_prod_readback_v2"
)
assert data["program_status"]["deploy_attempt_note"] == (
- "cd_3660_failed_host_pressure_guard_retry"
+ "cd_3673_retry_after_host_pressure_gate_fix"
)
assert data["current_policy"]["owner_review_required_for_low_medium_high"] is False
assert data["report_delivery"]["status"] == "telegram_gateway_delivery_enabled"
diff --git a/apps/api/tests/test_awooop_truth_chain_service.py b/apps/api/tests/test_awooop_truth_chain_service.py
index 563ae56f..d2e0a9a7 100644
--- a/apps/api/tests/test_awooop_truth_chain_service.py
+++ b/apps/api/tests/test_awooop_truth_chain_service.py
@@ -21,6 +21,7 @@ from src.services.awooop_ansible_check_mode_service import (
_post_apply_km_path_type,
_post_apply_verification_result,
_record_auto_repair_execution_receipt,
+ _send_controlled_apply_telegram_receipt,
build_ansible_apply_command,
build_ansible_check_mode_claim_input,
build_ansible_check_mode_command,
@@ -28,6 +29,7 @@ from src.services.awooop_ansible_check_mode_service import (
claim_pending_check_modes,
detect_ansible_transport_blockers,
recent_ansible_transport_blockers,
+ run_controlled_apply_for_claim,
)
from src.services.awooop_truth_chain_service import (
_ansible_playbook_roots,
@@ -1175,6 +1177,48 @@ def test_ansible_truth_surfaces_audited_check_mode_record() -> None:
)
+def test_ansible_truth_marks_worker_apply_as_controlled_apply() -> None:
+ truth = build_ansible_truth(
+ [
+ {
+ "op_id": "apply-op-1",
+ "operation_type": "ansible_apply_executed",
+ "status": "success",
+ "actor": "ansible_controlled_apply_worker",
+ "input_catalog_id": "ansible:188-momo-backup-user",
+ "input_execution_mode": "controlled_apply",
+ "input_playbook_path": "infra/ansible/playbooks/188-momo-backup-user.yml",
+ "input_apply_enabled": "true",
+ "output_apply_executed": "true",
+ "output_returncode": "0",
+ "tags": ["ansible", "controlled_apply", "low", "ai_agent_auto_execution"],
+ },
+ {
+ "op_id": "check-op-1",
+ "operation_type": "ansible_check_mode_executed",
+ "status": "success",
+ "actor": "ansible_check_mode_worker",
+ "input_catalog_id": "ansible:188-momo-backup-user",
+ "input_execution_mode": "check_mode",
+ "input_playbook_path": "infra/ansible/playbooks/188-momo-backup-user.yml",
+ "dry_run_result": {"check_mode_executed": True, "apply_executed": False},
+ "tags": ["ansible", "check_mode", "controlled_apply_allowed"],
+ },
+ ],
+ incident={"incident_id": "INC-MOMO", "alertname": "MomoPostgresBackupFailed"},
+ drift=None,
+ )
+
+ summary = truth["summary"]
+ assert summary["check_mode_total"] == 1
+ assert summary["apply_total"] == 1
+ assert summary["applied"] is True
+ assert summary["controlled_apply"] is True
+ assert summary["latest_actor"] == "ansible_controlled_apply_worker"
+ assert summary["latest_execution_mode"] == "controlled_apply"
+ assert summary["latest_apply_executed"] is True
+
+
def test_ansible_truth_keeps_catalog_hint_separate_from_runtime_use() -> None:
truth = build_ansible_truth(
[],
@@ -1548,6 +1592,16 @@ def test_ansible_apply_receipt_backfill_includes_verifier_and_km_gaps() -> None:
assert "_record_post_apply_verifier_and_learning" in source
+def test_ansible_live_controlled_apply_sends_telegram_receipt_but_backfill_does_not() -> None:
+ live_source = inspect.getsource(run_controlled_apply_for_claim)
+ backfill_source = inspect.getsource(backfill_missing_auto_repair_execution_receipts_once)
+
+ assert "_send_controlled_apply_telegram_receipt" in live_source
+ assert "telegram_receipt_sent" in live_source
+ assert "_send_controlled_apply_telegram_receipt" not in backfill_source
+ assert inspect.iscoroutinefunction(_send_controlled_apply_telegram_receipt)
+
+
def test_ansible_post_apply_verifier_helpers_are_deterministic() -> None:
assert _post_apply_km_path_type("03ca6836-1b76-4da2-8e3e-6d3b6df9254a") == (
"ansible_apply_receipt:03ca6836"
diff --git a/apps/api/tests/test_iwooos_wazuh_manager_registry_reviewer_validation.py b/apps/api/tests/test_iwooos_wazuh_manager_registry_reviewer_validation.py
index 7b943d95..ccadc9c3 100644
--- a/apps/api/tests/test_iwooos_wazuh_manager_registry_reviewer_validation.py
+++ b/apps/api/tests/test_iwooos_wazuh_manager_registry_reviewer_validation.py
@@ -78,13 +78,13 @@ def _valid_owner_export() -> dict:
}
-def test_iwooos_wazuh_manager_registry_reviewer_validation_contract_is_waiting_only() -> None:
+def test_iwooos_wazuh_manager_registry_reviewer_validation_contract_has_passed_redacted_export() -> None:
payload = load_latest_iwooos_wazuh_manager_registry_reviewer_validation()
assert payload["schema_version"] == "iwooos_wazuh_manager_registry_reviewer_validation_readback_v1"
assert payload["source_schema_version"] == "wazuh_manager_registry_reviewer_validation_v1"
- assert payload["status"] == "waiting_owner_registry_export_for_reviewer_validation"
- assert payload["mode"] == "committed_validation_contract_readback_no_runtime_no_secret_collection"
+ assert payload["status"] == "accepted_for_readonly_posture_only"
+ assert payload["mode"] == "committed_validation_passed_readback_no_runtime_no_secret_collection"
assert payload["summary"]["expected_scope_alias_count"] == 6
assert payload["summary"]["required_owner_field_count"] == 28
assert payload["summary"]["per_host_required_field_count"] == 9
@@ -92,15 +92,16 @@ def test_iwooos_wazuh_manager_registry_reviewer_validation_contract_is_waiting_o
assert payload["summary"]["outcome_lane_count"] == 13
assert payload["summary"]["evidence_slot_count"] == 6
assert payload["summary"]["forbidden_payload_count"] == 27
- assert payload["summary"]["owner_registry_export_received_count"] == 0
- assert payload["summary"]["owner_registry_export_accepted_count"] == 0
- assert payload["summary"]["reviewer_validation_passed_count"] == 0
+ assert payload["summary"]["owner_registry_export_received_count"] == 1
+ assert payload["summary"]["owner_registry_export_accepted_count"] == 1
+ assert payload["summary"]["reviewer_validation_ready_count"] == 1
+ assert payload["summary"]["reviewer_validation_passed_count"] == 1
assert payload["summary"]["reviewer_validation_quarantined_count"] == 0
assert payload["summary"]["manager_registry_accepted_count"] == 0
assert payload["summary"]["runtime_gate_count"] == 0
-def test_iwooos_wazuh_manager_registry_reviewer_validation_evidence_slots_are_closed() -> None:
+def test_iwooos_wazuh_manager_registry_reviewer_validation_evidence_slots_are_accepted_only_for_posture() -> None:
payload = load_latest_iwooos_wazuh_manager_registry_reviewer_validation()
assert [item["slot_id"] for item in payload["evidence_slots"]] == [
@@ -111,9 +112,10 @@ def test_iwooos_wazuh_manager_registry_reviewer_validation_evidence_slots_are_cl
"owner_response_and_rollback_owner",
"post_enable_iwooos_readback",
]
- assert all(item["received"] is False for item in payload["evidence_slots"])
- assert all(item["accepted"] is False for item in payload["evidence_slots"])
+ assert all(item["received"] is True for item in payload["evidence_slots"])
+ assert all(item["accepted"] is True for item in payload["evidence_slots"])
assert all(item["quarantined"] is False for item in payload["evidence_slots"])
+ assert all(item["next_gate"] == "post_enable_iwooos_readback" for item in payload["evidence_slots"])
assert "managed_core_node_a" in payload["expected_scope_aliases"]
assert "manager_registry_agent_counts" in [item["slot_id"] for item in payload["evidence_slots"]]
@@ -124,18 +126,23 @@ def test_iwooos_wazuh_manager_registry_reviewer_validation_api_is_public_safe()
assert response.status_code == 200
data = response.json()
assert data["schema_version"] == "iwooos_wazuh_manager_registry_reviewer_validation_readback_v1"
- assert data["summary"]["owner_registry_export_received_count"] == 0
- assert data["summary"]["owner_registry_export_accepted_count"] == 0
+ assert data["summary"]["owner_registry_export_received_count"] == 1
+ assert data["summary"]["owner_registry_export_accepted_count"] == 1
+ assert data["summary"]["reviewer_validation_passed_count"] == 1
assert data["summary"]["manager_registry_accepted_count"] == 0
assert data["summary"]["runtime_gate_count"] == 0
assert len(data["reviewer_validation_checks"]) == 10
assert len(data["evidence_slots"]) == 6
assert any(
- marker == "wazuh_manager_registry_reviewer_validation_owner_registry_export_received_count=0"
+ marker == "wazuh_manager_registry_reviewer_validation_owner_registry_export_received_count=1"
for marker in data["boundary_markers"]
)
assert any(
- marker == "wazuh_manager_registry_reviewer_validation_owner_registry_export_accepted_count=0"
+ marker == "wazuh_manager_registry_reviewer_validation_owner_registry_export_accepted_count=1"
+ for marker in data["boundary_markers"]
+ )
+ assert any(
+ marker == "wazuh_manager_registry_reviewer_validation_passed_count=1"
for marker in data["boundary_markers"]
)
assert any(
@@ -146,7 +153,7 @@ def test_iwooos_wazuh_manager_registry_reviewer_validation_api_is_public_safe()
marker == "wazuh_manager_registry_reviewer_validation_runtime_gate_count=0"
for marker in data["boundary_markers"]
)
- assert any(rule.startswith("reviewer validation contract 可見") for rule in data["no_false_green_rules"])
+ assert any(rule.startswith("reviewer validation passed") for rule in data["no_false_green_rules"])
assert data["boundaries"]["runtime_execution_authorized"] is False
assert data["boundaries"]["wazuh_active_response_authorized"] is False
assert data["boundaries"]["host_write_authorized"] is False
@@ -177,7 +184,7 @@ def test_iwooos_wazuh_manager_registry_owner_export_validation_accepts_redacted_
assert all(slot["accepted"] is True for slot in payload["evidence_slots"])
-def test_iwooos_wazuh_manager_registry_owner_export_validation_api_does_not_update_global_counters() -> None:
+def test_iwooos_wazuh_manager_registry_owner_export_validation_api_does_not_persist_payload_or_open_runtime() -> None:
client = _client()
response = client.post(
"/api/v1/iwooos/wazuh-manager-registry-reviewer-validation/validate-owner-export",
@@ -192,8 +199,9 @@ def test_iwooos_wazuh_manager_registry_owner_export_validation_api_does_not_upda
assert result["summary"]["runtime_gate_count"] == 0
readback = client.get("/api/v1/iwooos/wazuh-manager-registry-reviewer-validation").json()
- assert readback["summary"]["owner_registry_export_received_count"] == 0
- assert readback["summary"]["owner_registry_export_accepted_count"] == 0
+ assert readback["summary"]["owner_registry_export_received_count"] == 1
+ assert readback["summary"]["owner_registry_export_accepted_count"] == 1
+ assert readback["summary"]["reviewer_validation_passed_count"] == 1
assert readback["summary"]["manager_registry_accepted_count"] == 0
assert readback["summary"]["runtime_gate_count"] == 0
diff --git a/apps/api/tests/test_telegram_message_templates.py b/apps/api/tests/test_telegram_message_templates.py
index 887f6a94..30396502 100644
--- a/apps/api/tests/test_telegram_message_templates.py
+++ b/apps/api/tests/test_telegram_message_templates.py
@@ -1030,6 +1030,105 @@ def test_awooop_status_chain_lines_show_ansible_apply_proof() -> None:
assert ansible["approval_source"] == "user_chat_approved_continue"
+@pytest.mark.asyncio
+async def test_controlled_apply_result_receipt_marks_callback_reply_evidence(monkeypatch) -> None:
+ gateway = TelegramGateway()
+ sent_requests = []
+
+ async def fake_send_request(method, payload):
+ sent_requests.append((method, payload))
+ return {"ok": True, "result": {"message_id": 12345}}
+
+ async def fake_fetch_truth_chain(source_id, project_id):
+ assert source_id == "INC-20260627-64472B"
+ assert project_id == "awoooi"
+ return {
+ "truth_status": {
+ "current_stage": "execution_succeeded",
+ "stage_status": "success",
+ "needs_human": False,
+ "blockers": [],
+ },
+ "automation_quality": {
+ "verdict": "auto_repaired_verified",
+ "facts": {
+ "auto_repair_execution_records": 1,
+ "automation_operation_records": 3,
+ "effective_execution_records": 2,
+ "verification_result": "success",
+ "mcp_gateway_total": 8,
+ "knowledge_entries": 1,
+ },
+ "blockers": [],
+ },
+ "execution": {
+ "automation_operation_log": [
+ {
+ "operation_type": "ansible_apply_executed",
+ "status": "success",
+ "actor": "ansible_controlled_apply_worker",
+ "input_catalog_id": "ansible:188-momo-backup-user",
+ "input_execution_mode": "controlled_apply",
+ "input_playbook_path": "infra/ansible/playbooks/188-momo-backup-user.yml",
+ }
+ ],
+ "ansible": {
+ "considered": True,
+ "records": [
+ {
+ "operation_type": "ansible_apply_executed",
+ "status": "success",
+ "actor": "ansible_controlled_apply_worker",
+ "catalog_id": "ansible:188-momo-backup-user",
+ "playbook_path": "infra/ansible/playbooks/188-momo-backup-user.yml",
+ "execution_mode": "controlled_apply",
+ "apply_executed": True,
+ "returncode": 0,
+ "tags": ["ansible", "controlled_apply", "ai_agent_auto_execution"],
+ }
+ ],
+ "candidate_catalog": {"candidates": []},
+ },
+ },
+ }
+
+ monkeypatch.setattr(TelegramGateway, "alert_chat_id", property(lambda _self: "chat"))
+ monkeypatch.setattr(gateway, "_send_request", fake_send_request)
+ monkeypatch.setattr(
+ "src.services.awooop_truth_chain_service.fetch_truth_chain",
+ fake_fetch_truth_chain,
+ )
+
+ result = await gateway.send_controlled_apply_result_receipt(
+ incident_id="INC-20260627-64472B",
+ catalog_id="ansible:188-momo-backup-user",
+ apply_op_id="73b7a95c-3652-4c0d-bb4c-729e500acedb",
+ playbook_path="infra/ansible/playbooks/188-momo-backup-user.yml",
+ verification_result="success",
+ returncode=0,
+ duration_ms=7727,
+ verifier_written=True,
+ learning_written=True,
+ project_id="awoooi",
+ )
+
+ assert result["ok"] is True
+ assert sent_requests
+ method, payload = sent_requests[0]
+ assert method == "sendMessage"
+ assert "CONTROLLED APPLY RESULT" in payload["text"]
+ assert "INC-20260627-64472B" in payload["text"]
+ assert "ansible:188-momo-backup-user" in payload["text"]
+ source_extra = payload["_awooop_source_envelope_extra"]
+ assert source_extra["callback_reply"]["action"] == "controlled_apply_result"
+ assert source_extra["callback_reply"]["status"] == "callback_reply_sent"
+ assert source_extra["source_refs"]["incident_ids"] == ["INC-20260627-64472B"]
+ snapshot = source_extra["awooop_status_chain"]
+ assert snapshot["repair_state"] == "auto_repaired_verified"
+ assert snapshot["operator_outcome"]["state"] == "completed_verified"
+ assert snapshot["execution"]["ansible"]["controlled_apply"] is True
+
+
def test_callback_reply_awooop_status_chain_snapshot_marks_manual_gate() -> None:
"""Callback evidence 要保存當下 AwoooP 狀態鏈,不只保存 live query 結果。"""
snapshot = telegram_gateway_module._callback_reply_awooop_status_chain_snapshot(
diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json
index b465eb38..0e1a6c98 100644
--- a/apps/web/messages/en.json
+++ b/apps/web/messages/en.json
@@ -934,7 +934,7 @@
"incidentFlow": {
"standard": "BPMN / Swimlane",
"title": "告警到修復流程",
- "detail": "用泳道圖拆開 Telegram、OpenClaw、Hermes、MCP、Ansible、人工審批與驗證責任。",
+ "detail": "用泳道圖拆開 Telegram、OpenClaw、Hermes、MCP、Ansible、AI 受控審批與驗證責任。",
"nodes": {
"alert": "Alert / Sentry / SigNoz",
"ai": "AI 分析",
@@ -1129,7 +1129,7 @@
},
"approval": {
"metric": "pending {pending} / verified {verified}/{evaluated}",
- "detail": "人工閘門 {humanGates},自動修復紀錄 {autoRepairRecords},操作紀錄 {operations}"
+ "detail": "AI 受控閘門 {humanGates},自動修復紀錄 {autoRepairRecords},操作紀錄 {operations}"
},
"verify": {
"metric": "stale {stale} / ratio {ratio}",
@@ -2452,7 +2452,7 @@
},
"sourceGapActions": {
"title": "PlayBook / Verifier 缺口處置板",
- "subtitle": "每個 report-source-gap 都要有服務專屬 PlayBook 草案、Verifier 計畫、腳本與排程邊界,不能只丟給人工判斷。",
+ "subtitle": "每個 report-source-gap 都要有服務專屬 PlayBook 草案、Verifier 計畫、腳本與排程邊界,不能只停在人工判斷。",
"playbook": "PlayBook 草案",
"verifier": "Verifier 計畫",
"script": "腳本",
@@ -2472,11 +2472,11 @@
},
"funnel": {
"title": "告警到 AI 接手漏斗",
- "subtitle": "快速看出訊號是否進來、處置是否形成、AI 能否接手、還有多少卡在人工或審核。",
+ "subtitle": "快速看出訊號是否進來、處置是否形成、AI 能否接手、還有多少卡在補齊或審核。",
"alerts": "告警訊號",
"dispositions": "處置紀錄",
"auto": "AI / 冷啟動接手",
- "human": "人工處置",
+ "human": "AI 補齊處置",
"waiting": "待審核工作"
},
"assets": {
@@ -3467,18 +3467,18 @@
"blockedBoundary": "阻擋邊界",
"escalation": "升級條件",
"readOnlyReady": "只讀可推進",
- "ownerGate": "需負責人閘門",
+ "ownerGate": "受控 / break-glass 閘門",
"reportOwnership": "報告責任",
"presets": {
"openclaw": {
"lane": "生產仲裁 / 高風險 gate",
"question": "候選 Agent 是否已通過 replay、shadow、canary、成本、安全與可觀測性證據,足以改變生產決策?",
- "escalation": "只有 replay / shadow / canary 與 owner approval 全部補齊後,才可進入 provider switch 或 OpenClaw replacement review。"
+ "escalation": "只有 replay / shadow / canary、controlled gate 與 verifier 全部補齊後,才可進入 provider switch 或 OpenClaw replacement review。"
},
"hermes": {
"lane": "報告治理 / 知識沉澱",
"question": "日報、週報、月報是否已把證據、圖表、RAG 摘要與 no-send Telegram 草稿整理到可審核狀態?",
- "escalation": "只要涉及實發 Telegram、Bot API、report receipt write 或未脫敏來源內容,就必須停在負責人閘門。"
+ "escalation": "實發 Telegram、Bot API 與 report receipt write 走受控 Gateway / verifier;未脫敏來源內容與 critical 外發才進 break-glass。"
},
"nemotron": {
"lane": "離線 replay / 模型能力比較",
@@ -3492,8 +3492,8 @@
},
"reviewer": {
"lane": "交叉審查 / owner queue",
- "question": "跨 Agent 產出的證據是否足以支持低中風險自動處理,或必須升級成高風險 owner review?",
- "escalation": "只要涉及 live query、runtime write、機密、部署或外部發送,就維持人工批准。"
+ "question": "跨 Agent 產出的證據是否足以支持低 / 中 / 高風險 controlled apply,或必須升級成 critical break-glass?",
+ "escalation": "live query、runtime write、部署或外部發送走 allowlist、check-mode、verifier 與 rollback;機密、破壞性 DB、付費 provider、force push 才進 break-glass。"
}
}
},
@@ -3542,7 +3542,7 @@
"runtimeReadback": "Runtime readback",
"resultCapture": "Result capture 寫入",
"productionWrite": "Production 寫入",
- "ownerApproval": "Owner 批准",
+ "ownerApproval": "Critical / break-glass",
"note": "真相註記"
}
},
@@ -3581,11 +3581,11 @@
"schedule": "排程",
"nextRun": "下次執行",
"sourcePolicy": "來源政策",
- "reviewGate": "人工關卡",
+ "reviewGate": "受控關卡",
"triggerModes": "觸發模式"
},
"decisionQueue": {
- "title": "人工決策佇列",
+ "title": "AI 受控決策佇列",
"priority": "P",
"status": "狀態",
"nextAction": "下一步",
@@ -3596,8 +3596,8 @@
"statuses": {
"baseline_protected": "基準受保護",
"blocked_needs_evidence": "需要證據",
- "operator_review_required": "需要人工審查",
- "operator_priority_review": "優先級審查",
+ "operator_review_required": "需要受控審查",
+ "operator_priority_review": "優先級受控審查",
"watch_only_blocked": "觀察已阻擋",
"watch_only_monitoring": "觀察中",
"registered_no_review": "尚未審查"
@@ -3662,7 +3662,7 @@
"metrics": {
"backlog": "待辦進度",
"readback": "讀回關卡",
- "gates": "人工 gate",
+ "gates": "受控 gate",
"liveWrites": "正式寫入"
}
},
@@ -3712,7 +3712,7 @@
"low": "低風險",
"medium": "中風險",
"high": "高風險",
- "noOwnerReview": "低/中/高人工 gate={value}",
+ "noOwnerReview": "低/中/高 owner_review_required={value}",
"verifier": "post-apply verifier={value}",
"km": "KM / PlayBook 回寫={value}"
},
@@ -3727,22 +3727,22 @@
"readOnlyInvestigation": {
"label": "主動巡檢與證據蒐集",
"detail": "只讀探針 {probes} 個,服務需處置訊號 {health} 個。",
- "next": "下一步:整理 owner packet;runtime blocker {blocked} 個。"
+ "next": "下一步:整理 controlled packet;runtime blocker {blocked} 個。"
},
"dryRunCandidate": {
- "label": "乾跑候選與套用審查",
+ "label": "乾跑候選與受控套用",
"detail": "乾跑證據 {evidence} 筆,Verifier plan {verifier} 個。",
- "next": "下一步:{review} 個候選進 owner review,不直接執行。"
+ "next": "下一步:{review} 個候選進 controlled apply 檢查,不繞過 verifier。"
},
"shadowReplay": {
"label": "Nemotron replay / shadow",
"detail": "無寫入 replay {replays} 次,Verifier shadow case {verifier} 個。",
- "next": "下一步:{approvals} 個 checkpoint 需批准才可升級。"
+ "next": "下一步:{approvals} 個 checkpoint 需 controlled gate 才可升級。"
},
"permissionModel": {
"label": "操作權限模型",
"detail": "Gate transition {gates} 條,blocked category {blocked} 個。",
- "next": "下一步:{approvals} 類仍需人工批准。"
+ "next": "下一步:{approvals} 類進 controlled gate;critical 才 break-glass。"
},
"reportTelegram": {
"label": "日週月報與 Telegram receipt",
@@ -3758,7 +3758,7 @@
"agentWorkload": {
"title": "AI Agent 工作量與專業分工",
"badge": "OpenClaw / Hermes / Nemotron / Security-SRE",
- "summary": "目前可見工作量 {workload} 件;其中負責人審核 {review} 件、阻擋 {blocked} 件,正式寫入 / Telegram / 機密讀取 / 破壞性操作邊界總數 {live}。",
+ "summary": "目前可見工作量 {workload} 件;其中受控審查 {review} 件、阻擋 {blocked} 件,正式寫入 / Telegram / 機密讀取 / 破壞性操作邊界總數 {live}。",
"labels": {
"review": "審核 {count}",
"blocked": "阻擋 {count}"
@@ -3766,10 +3766,10 @@
"agents": {
"openclaw": {
"label": "OpenClaw",
- "mission": "仲裁、風險分級、乾跑候選與負責人審核包主責;不靠身份保護,仍接受市場與回放數據挑戰。",
- "telegram": "Telegram:{reviews} 件需審核時只產摘要/批准包,不直接發正式處置。",
+ "mission": "仲裁、風險分級、乾跑候選與受控審查包主責;不靠身份保護,仍接受市場與回放數據挑戰。",
+ "telegram": "Telegram:{reviews} 件需審核時只產摘要/受控處置包,不直接繞過 Gateway。",
"learning": "學習:承接 {candidates} 個 PlayBook / KM 候選,等待 gate 後寫回。",
- "next": "下一步:整理 {dryRuns} 個乾跑候選與 {high} 個高風險審核包。"
+ "next": "下一步:整理 {dryRuns} 個乾跑候選與 {high} 個高風險 controlled apply 包。"
},
"hermes": {
"label": "Hermes",
@@ -3812,7 +3812,7 @@
"criticReplay": {
"label": "Critic 回放評分",
"detail": "回放 {replays} 次、scorecard {scorecards} 張,shadow 通過 {passed}/{total}。",
- "next": "下一步:{approvals} 個升級 checkpoint 等 owner review。"
+ "next": "下一步:{approvals} 個升級 checkpoint 等 controlled review。"
},
"telegramReceipt": {
"label": "Telegram 回執閉環",
@@ -3829,16 +3829,16 @@
"professionalJudgment": {
"title": "AI Agent 專業判斷矩陣",
"badge": "判斷依據 / 信心 / 建議 / Gate",
- "summary": "目前顯示 {agents} 位 Agent 的專業判斷;採用證據 {evidence} 件,需 gate / owner review {gates} 件,正式寫入與 Telegram 實送邊界 {live}。",
+ "summary": "目前顯示 {agents} 位 Agent 的專業判斷;採用證據 {evidence} 件,需 controlled gate / break-glass {gates} 件,正式寫入與 Telegram 實送邊界 {live}。",
"auditLine": "邊界:只讀取治理快照與脫敏證據;deploy marker + production readback 才算上線,非產品對話、secrets、Telegram token、runtime write 全部不展示、不送出。",
"items": {
"openclaw": {
- "role": "仲裁與風險分級:先看乾跑證據、owner packet 與高風險接受度。",
- "judgment": "判斷:乾跑需審 {dryRuns},高風險 {high},已接受 owner response {accepted};未接受前只做候選與審核包。",
+ "role": "仲裁與風險分級:先看乾跑證據、controlled packet 與高風險 verifier。",
+ "judgment": "判斷:乾跑需審 {dryRuns},高風險 {high},已接受控制證據 {accepted};未通過前只做候選與審核包。",
"evidence": "證據 {evidence} / packet {packets}",
"confidence": "低/中 {low}/{medium}",
- "recommendation": "建議:blocked {blocked} 先維持人工 gate,不升級 runtime。",
- "gate": "Gate:OpenClaw owner review {reviews}。"
+ "recommendation": "建議:blocked {blocked} 先維持 controlled gate,不升級 runtime。",
+ "gate": "Gate:OpenClaw controlled review {reviews}。"
},
"hermes": {
"role": "報告與記憶:把工作量、回執、圖表與 RAG / KM 摘要整理成可讀證據。",
@@ -3861,7 +3861,7 @@
"judgment": "判斷:gate {gates}、權限類別 {categories}、blocked {blocked};先保障不誤執行。",
"evidence": "Verifier {verifiers} / health {health}",
"confidence": "write {write} / TG {telegram}",
- "recommendation": "建議:高風險 {high} 先整理 owner packet 與 rollback owner。",
+ "recommendation": "建議:高風險 {high} 先整理 controlled packet、rollback 與 verifier。",
"gate": "Gate:runtime / write blocked {blocked}。"
}
}
@@ -3869,7 +3869,7 @@
"autonomyMaturity": {
"title": "AI Agent 自動化成熟度與接管缺口",
"badge": "Sensor → Candidate → Gate → Verifier → Learning",
- "summary": "目前追蹤 {rows} 條成熟度鏈;證據 {evidence} 件,可自動準備 {prepared} 件,待 Gate / owner review {gates} 件,正式寫入 {live}。",
+ "summary": "目前追蹤 {rows} 條成熟度鏈;證據 {evidence} 件,可自動準備 {prepared} 件,待 controlled gate / break-glass {gates} 件,正式寫入 {live}。",
"stages": {
"sensor": "L1-L2 Sensor / Evidence",
"candidate": "L3-L4 Candidate / Dry-run",
@@ -3933,7 +3933,7 @@
"marketRadar": "版本雷達",
"noSendPreview": "無發送報告預覽",
"autoPrepare": "自動準備候選",
- "ownerReview": "owner review",
+ "ownerReview": "controlled review",
"shadowReplay": "shadow replay",
"learningDraft": "學習草稿"
},
@@ -3964,7 +3964,7 @@
"versionRadar": {
"label": "套件、工具、AI 技術版本雷達",
"detail": "過期來源 {stale}、漂移/升級候選 {candidates}。",
- "next": "Nemotron 做 no-write 比對,blocked 操作 {blocked} 先轉 owner packet。"
+ "next": "Nemotron 做 no-write 比對,blocked 操作 {blocked} 先轉 controlled packet。"
},
"reportOps": {
"label": "日報 / 週報 / 月報產製",
@@ -4014,7 +4014,7 @@
"ownerGate": "Owner gate 後通知"
},
"learning": {
- "ownerReview": "維護窗與 owner review 寫回待批准。",
+ "ownerReview": "維護窗與 controlled review 寫回待批准。",
"snapshot": "以 committed snapshot 累積資產知識。",
"redactedEvidence": "只寫入脫敏證據,不寫入未脫敏紀錄。",
"versionRadar": "版本雷達產生候選,升級仍需 gate。",
@@ -4444,7 +4444,7 @@
"tool_install_or_ci_change_approval_required": "工具安裝或 CI 變更需批准",
"workflow_and_bot_approval_required": "workflow 與 bot 需批准",
"workflow_modification_approval_required": "workflow 修改需批准",
- "write_requires_human_gate": "寫入需人工關卡",
+ "write_requires_human_gate": "寫入需受控關卡",
"cost_data_approval_required": "需費用與資料邊界批准"
}
},
@@ -5180,7 +5180,7 @@
"readinessTitle": "準備度矩陣",
"policyTitle": "通知政策",
"targetsTitle": "關鍵備份目標",
- "noBlocker": "無目標層阻擋;restore 仍需人工批准。",
+ "noBlocker": "無目標層阻擋;restore 仍需 break-glass 批准。",
"noEvidence": "尚無證據",
"metrics": {
"targets": "目標",
@@ -7094,14 +7094,14 @@
}
},
"ownerApprovedFixturePromotionGate": {
- "title": "P2-114 負責人批准 fixture promotion gate",
+ "title": "P2-114 controlled fixture promotion gate",
"source": "產生 {generated};目前 {current};下一步 {next}",
"priorGateTitle": "前一關 promotion gate",
- "truthTitle": "Owner approval truth",
+ "truthTitle": "Controlled approval truth",
"redactionTitle": "前端遮蔽契約",
"metrics": {
"overall": "完成度",
- "packets": "owner packet",
+ "packets": "controlled packet",
"templates": "acceptance template",
"reviews": "fixture review",
"verifiers": "無寫入 verifier",
@@ -7110,7 +7110,7 @@
"approvalRequired": "需批准",
"blocked": "阻擋",
"critical": "critical blocker",
- "ownerApprovals": "owner 批准",
+ "ownerApprovals": "critical 批准",
"acceptanceWrites": "acceptance 寫入",
"executions": "promotion 執行",
"canonicalReads": "canonical 讀取",
@@ -7131,7 +7131,7 @@
"promotionGateLoaded": "P2-113 loaded={value}",
"packageReady": "package ready={value}",
"acceptanceReady": "acceptance ready={value}",
- "ownerApproval": "負責人批准={value}",
+ "ownerApproval": "break-glass 批准={value}",
"telegramSend": "Telegram 發送={value}",
"resultWrite": "結果寫入={value}",
"redactionRequired": "redaction={value}",
@@ -7154,7 +7154,7 @@
"runtimePromotionAllowed": "runtime promotion={value}"
},
"packetStatuses": {
- "ready_for_owner_review": "待 負責人審查",
+ "ready_for_owner_review": "待受控審查",
"approval_required": "需批准",
"blocked_by_policy": "政策阻擋"
},
@@ -7187,7 +7187,7 @@
"critical": "關鍵"
},
"actionTypes": {
- "review_owner_packet": "審查 owner packet",
+ "review_owner_packet": "審查 controlled packet",
"verify_acceptance_template": "驗證 acceptance template",
"confirm_verifier_plan": "確認 verifier plan",
"lock_blocked_promotion": "鎖定 blocked promotion",
@@ -7197,7 +7197,7 @@
"canonicalRuntimeReadbackOwnerAcceptance": {
"title": "P2-115 canonical runtime readback 負責人驗收",
"source": "產生 {generated};目前 {current};下一步 {next}",
- "priorGateTitle": "前一關 owner promotion gate",
+ "priorGateTitle": "前一關 controlled promotion gate",
"truthTitle": "Canonical readback 負責人驗收 truth"
},
"failureReceiptNoSendReplay": {
@@ -8613,9 +8613,9 @@
"route": "流向:Run 監控 / 事件詳情"
},
"approval": {
- "title": "人工閘門",
- "signal": "高風險待批准",
- "owner": "負責:SRE approve / reject",
+ "title": "AI 受控閘門",
+ "signal": "低 / 中 / 高風險待 AI policy / verifier 判定",
+ "owner": "負責:AI policy + SRE break-glass reviewer",
"route": "流向:審批佇列"
},
"execute": {
@@ -8625,9 +8625,9 @@
"route": "流向:執行狀態 / Audit"
},
"manual": {
- "title": "人工升級",
- "signal": "AI 無法安全修復",
- "owner": "負責:戰情室接手",
+ "title": "AI 補齊升級",
+ "signal": "缺 PlayBook / verifier / rollback",
+ "owner": "負責:AI 戰情室補齊",
"route": "流向:AwoooI SRE 戰情室"
}
},
@@ -8820,7 +8820,7 @@
},
"highValueConfigOwnerPacket": {
"title": "高價值配置 Owner Packet",
- "subtitle": "AwoooP 首頁只讀顯示 IwoooS 產生的高價值配置 owner packet 草案;目前只是收件候選狀態,不送 request、不標記收到或接受,也不開任何執行期入口。",
+ "subtitle": "AwoooP 首頁只讀顯示 IwoooS 產生的高價值配置 controlled packet 草案;目前只是收件候選狀態,不送 request、不標記收到或接受,也不開任何執行期入口。",
"badge": "只讀 packet",
"openIwooos": "開啟 IwoooS",
"refsTitle": "Owner packet 參照",
@@ -8846,7 +8846,7 @@
}
},
"refs": {
- "packetDraft": "高價值配置 owner packet 草案已由分類 Gate 產生,但尚未送出。",
+ "packetDraft": "高價值配置 controlled packet 草案已由分類 Gate 產生,但尚未送出。",
"c0Scope": "目前快照已有 Nginx public gateway 與 DNS / TLS / certbot C0 packet;仍只進 owner gate,不代表 reload、renew 或 route change。",
"s49Envelope": "欄位沿用 S4.9 canonical owner response envelope,但收件與接受計數仍是 0。",
"runtimeBoundary": "IwoooS projection 固定 runtime gate 0,AwoooP 只能鏡像狀態。"
@@ -8868,8 +8868,8 @@
},
"operatorSop": {
"eyebrow": "操作 SOP 判讀",
- "title": "人工卡點與自動化缺口接手面板",
- "subtitle": "把阻塞、修復候選、資產沉澱與負責人審查集中成一條操作 rail;先判斷狀態,再下鑽 Runs、工作項、總帳與批准。",
+ "title": "AI 受控卡點與自動化缺口接手面板",
+ "subtitle": "把阻塞、修復候選、資產沉澱與 controlled review 集中成一條操作 rail;先判斷狀態,再下鑽 Runs、工作項、總帳與受控批准。",
"boundary": "此面板只做只讀導覽與下一步判讀;不觸發通知、不改服務、不套用腳本,也不代表 runtime gate 已開。",
"metrics": {
"verifiedRate": "驗證率",
@@ -8884,15 +8884,15 @@
"conclusion": {
"label": "一眼判讀",
"blocked": {
- "title": "目前仍有人工卡點,不能宣稱全自動閉環",
- "detail": "先看阻塞工作項與人工閘門,再補 PlayBook、Verifier、rollback 與 owner review。"
+ "title": "目前仍有 AI 受控卡點,不能宣稱全自動閉環",
+ "detail": "先看阻塞工作項與 AI 受控閘門,再補 PlayBook、Verifier、rollback 與 controlled review。"
},
"inProgress": {
"title": "自動化資產正在補齊,仍需追蹤候選品質",
"detail": "優先確認候選是否有證據 refs、安全路由、回滾計畫與修復後驗證。"
},
"watching": {
- "title": "目前沒有明顯人工卡點,持續觀察資料新鮮度",
+ "title": "目前沒有明顯 AI 受控卡點,持續觀察資料新鮮度",
"detail": "若日報、週報、告警或來源突然歸零,仍要回到 Runs 與來源健康檢查。"
}
},
@@ -8911,7 +8911,7 @@
},
"owner": {
"title": "接手",
- "detail": "人工閘門與負責人審查"
+ "detail": "AI 受控閘門與負責人審查"
},
"verifier": {
"title": "驗證",
@@ -8920,8 +8920,8 @@
},
"cards": {
"blockers": {
- "title": "阻塞與人工閘門",
- "detail": "阻塞工作項 {workItems};人工閘門 {manual};資產阻塞 {assets}。",
+ "title": "阻塞與 AI 受控隊列",
+ "detail": "阻塞工作項 {workItems};AI 受控閘門 {manual};資產阻塞 {assets}。",
"action": "查看工作項"
},
"candidates": {
@@ -8936,21 +8936,21 @@
},
"owners": {
"title": "負責人接手",
- "detail": "人工閘門 {manual};來源審查 {source};已記錄 {recorded}。",
+ "detail": "AI 受控閘門 {manual};來源審查 {source};已記錄 {recorded}。",
"action": "查看審查"
}
}
},
"automationBlockerMap": {
"eyebrow": "告警自動化卡點總盤",
- "title": "為什麼仍需人工處理",
+ "title": "為什麼仍需 AI 補齊處理",
"subtitle": "把焦點事故從收件、證據、候選、PlayBook、安全路由、放行、Verifier 到學習回寫拆成可量化 lane;先看卡在哪裡,再看下方詳細證據。",
"completion": "自動化閉環就緒度",
"boundary": "目前仍有 {blocked} 個阻擋點;這是只讀判讀,不代表 runtime gate 已開或可直接套用修復。",
"blockedLabel": "卡點 {count}",
"nextAction": "下一步:{value}",
"metrics": {
- "manual": "人工閘門",
+ "manual": "AI 受控閘門",
"gap": "自動化缺口",
"verified": "已驗證修復",
"runtime": "Runtime gate"
@@ -9040,7 +9040,7 @@
},
"playbook": {
"title": "PlayBook",
- "detail": "OpenClaw 修復候選、服務專屬策略、trust 與人工閘門。",
+ "detail": "OpenClaw 修復候選、服務專屬策略、trust 與 AI 受控閘門。",
"next": "下一步:把通用兜底改成服務專屬 PlayBook,補 rollback 與適用條件。"
},
"script": {
@@ -9056,7 +9056,7 @@
"verifier": {
"title": "Verifier",
"detail": "status-chain、remediation history、quality summary 與最終驗證。",
- "next": "下一步:每次修復或人工接手都必須留下 success / degraded / failed 判定。"
+ "next": "下一步:每次修復、AI 補齊或 break-glass 都必須留下 success / degraded / failed 判定。"
}
},
"sources": {
@@ -9202,7 +9202,7 @@
"gates": {
"sourceDossier": "入站告警必須能查到 received / incident_linked / 來源 refs",
"autoRepair": "必須同時有 auto_repair、verification_result=success與KM 回寫",
- "recurrenceWorkItems": "Run 完成無修復、修復失敗與人工閘門必須進入可追蹤工作項",
+ "recurrenceWorkItems": "Run 完成無修復、修復失敗與 AI 受控閘門必須進入可追蹤工作項",
"aiRouteRepairWorkItem": "Provider lane 降級時必須顯示 evidence、owner、PlayBook候選與是否可自動修復",
"reportSourceGapOwnerReview": "每個 report-source-gap 必須有 PlayBook 草案、Verifier 計畫、腳本 readback、排程 無發送 與 負責人審查;不得把全 0 當健康或自動執行授權",
"configDriftFsm": "同一 drift fingerprint 必須顯示重複、PR、零 diff、交接與下一步",
@@ -9223,7 +9223,7 @@
"evidence": {
"channelEvents": "最近 Alertmanager 通道事件:{count}",
"autoRepair": "已驗證自動修復:{verified}/{evaluated}",
- "recurrenceWorkItems": "重複告警待處理:{open};無修復:{gap};修復失敗:{failed};人工閘門:{manual};來源待審:{source}",
+ "recurrenceWorkItems": "重複告警待處理:{open};無修復:{gap};修復失敗:{failed};AI 受控閘門:{manual};來源待審:{source}",
"recurrenceLatest": "最新:{alert} / {incident}",
"recurrenceReason": "原因:{reason}",
"recurrenceSourceReviewRecorded": "來源審核已寫入歷史:{count}",
@@ -9242,7 +9242,7 @@
"aiRouteRepairOwner": "Owner:{owner};主責 Agent:{lead}",
"aiRouteRepairPlaybook": "PlayBook:{playbook};步驟 {steps}",
"aiRouteRepairSafety": "可安全自動修復:{safe}",
- "aiRouteRepairSummary": "AI route 目前由 {selected} 承接;下一步:{action};需人工介入:{human}",
+ "aiRouteRepairSummary": "AI route 目前由 {selected} 承接;下一步:{action};需 AI 補齊:{human}",
"aiRouteRepairUnavailable": "AI route repair evidence 尚未回傳",
"reportSourceGapOwnerReview": "報表資料源缺口:{gaps};PlayBook 草案 {playbooks};Verifier 計畫 {verifiers};需 owner {owners}",
"reportSourceGapLatest": "最新工作項:{workItem};route={route}",
@@ -9318,7 +9318,7 @@
},
"adr100Remediation": {
"title": "ADR-100 補救工作佇列",
- "subtitle": "補救 {total} 筆;AI可接手 {ready};需人工 / PlayBook 改造 {human}",
+ "subtitle": "補救 {total} 筆;AI可接手 {ready};需 AI 補齊 / PlayBook 改造 {human}",
"openGovernance": "開啟治理",
"empty": "目前沒有非成功驗證補救工作;若 SLO 再出現 degraded / failed,會在這裡形成可操作項。",
"unknownAlert": "未知告警",
@@ -9357,7 +9357,7 @@
"closed": "已符合關閉條件,保留歷史證據即可",
"investigateActiveGap": "仍有新缺口,檢查新 Telegram reply_markup trace 寫入",
"verifyInstrumentation": "沒有復原訊號,檢查 TelegramGateway / 時間線觀測埋點",
- "waitDecay": "等待舊 backlog 24h decay,不需人工處理",
+ "waitDecay": "等待舊 backlog 24h decay,不需 AI 補齊處理",
"observeRecovery": "觀察復原訊號,先不開人工任務"
},
"claim": {
@@ -9588,7 +9588,7 @@
},
"readiness": {
"ready": "可乾跑",
- "blocked": "需人工排除",
+ "blocked": "需 AI 補齊排除",
"completed": "已完成",
"failed": "失敗待處理"
}
@@ -9949,7 +9949,7 @@
"flow": {
"ingest": {
"title": "告警接收",
- "detail": "事件已進入 AwoooP 真相鏈與 Telegram 人工處置面。"
+ "detail": "事件已進入 AwoooP 真相鏈與 Telegram AI 受控處置面。"
},
"evidence": {
"title": "證據補齊",
@@ -9975,10 +9975,10 @@
"mcp_evidence_refs": "MCP / Sentry / SigNoz / K8s / log 證據參照。",
"repair_command": "受控修復命令或 Ansible playbook,不能是純診斷命令。",
"rollback_command": "修復失敗時的回滾或安全停止方案。",
- "verifier_plan": "修復後如何驗證成功、失敗與是否要升級人工。",
+ "verifier_plan": "修復後如何驗證成功、失敗與是否要升級 AI 補齊或 break-glass。",
"owner_review": "負責人、風險等級、適用條件與批准紀錄。",
"script_or_ansible_ref": "腳本或 Ansible 參照,必須能被安全路由與 reviewer 查到。",
- "schedule_or_monitoring_rule_ref": "排程、監控規則或 recurrence 偵測參照,避免同類告警只靠人工記憶。",
+ "schedule_or_monitoring_rule_ref": "排程、監控規則或 recurrence 偵測參照,避免同類告警只靠人工記憶或口頭交接。",
"km_update_plan": "KM 更新草稿與 負責人審查 計畫,避免錯知識直接固化。",
"automation_asset_record": "自動化資產紀錄,包含 asset id、owner、狀態、來源與下一步。"
},
@@ -10018,21 +10018,21 @@
"writebackTitle": "必須回寫的結果",
"writebacks": {
"incident_timeline_stage_update": "Incident timeline 必須標記目前階段、處置包、owner 與下一步。",
- "execution_or_manual_handoff_result": "無執行時也要寫入人工接手結果,不能只留下批准紀錄。",
+ "execution_or_manual_handoff_result": "無執行時也要寫入 AI 補齊或 break-glass 結果,不能只留下批准紀錄。",
"verifier_result": "Verifier 要能記錄成功、失敗、降級或尚未執行。",
"km_update_draft": "Hermes 產生 KM 草稿,負責人審查 後才可寫入高影響知識。",
"playbook_trust_update": "PlayBook 成功 / 失敗 / 未執行都要回寫 trust 與適用條件。",
"automation_asset_inventory_record": "資產清冊要留下 KM、PlayBook、腳本、排程、Verifier 的 ID 與狀態。"
},
"guardrailTitle": "阻擋原因與禁止誤讀",
- "blocker": "目前缺少可信修復候選;系統只能建立人工草案工作項,不能把 no-action、診斷結果或通用兜底當作已修復。",
+ "blocker": "目前缺少可信修復候選;系統必須建立 AI 補齊草案工作項,不能把 no-action、診斷結果或通用兜底當作已修復。",
"nextStep": "請先補 PlayBook 草案與 MCP evidence,再由 負責人審查 決定是否送審批;在此之前不會自動執行、不會寫入成功修復,也不會更新 KM 為已解決。",
"chainTitle": "真相鏈對照",
"chain": {
"stage": "目前階段",
"repair": "修復狀態",
"next": "真相鏈下一步",
- "human": "需要人工"
+ "human": "需要 AI 補齊"
},
"chainHint": "下方完整 status-chain 與 incident timeline 會用同一個 Incident 查詢;如果仍沒有資料,代表資料鏈路還沒把這筆告警完整串上。",
"openRuns": "打開 Runs",
@@ -10040,7 +10040,7 @@
},
"recurrence": {
"title": "重複告警工作項",
- "subtitle": "把 run_completed_no_repair、修復失敗與人工閘門接成可追蹤 work item",
+ "subtitle": "把 run_completed_no_repair、修復失敗與 AI 受控閘門接成可追蹤 work item",
"open": "待處理 {count}",
"automationGap": "無修復 {count}",
"failed": "修復失敗 {count}",
@@ -10110,7 +10110,7 @@
},
"handoffKinds": {
"ticket_proposal": "Ticket 提案",
- "manual_review": "人工覆核",
+ "manual_review": "AI 補齊覆核",
"unknown": "未知"
},
"handoffStatuses": {
@@ -10157,7 +10157,7 @@
"auto_repair_succeeded_unverified": "修復待驗證",
"auto_repair_failed": "修復失敗",
"auto_repair_recorded": "修復已記錄",
- "manual_gate": "需人工閘門",
+ "manual_gate": "需 AI 受控閘門",
"investigating": "調查中",
"run_completed_no_repair": "Run 完成無修復",
"source_correlation_review": "來源證據待配對",
@@ -10229,7 +10229,7 @@
"nextStatusChain": "等待狀態鏈批次回補,或打開 Incident 詳情確認",
"statusChainPending": "狀態鏈待回補",
"statuses": {
- "needsHuman": "需人工",
+ "needsHuman": "需 AI 補齊",
"failed": "執行失敗",
"verified": "已驗證",
"executed": "已執行",
@@ -10249,7 +10249,7 @@
"mcpCount": "MCP 調查 {count} 次",
"route": "MCP:{route}",
"emptyShort": "尚未連到 AI 證據",
- "manualGate": "下一步:人工審批",
+ "manualGate": "下一步:AI 受控審批",
"filters": {
"label": "AI 證據篩選",
"all": "所有 AI 證據",
@@ -10275,7 +10275,7 @@
"mcpObserved": "AI 已透過 MCP / 自建 MCP 收集證據,但尚未進入補救試跑或執行。",
"readOnlyDryRun": "AI 已走補救試跑,且最新紀錄沒有寫入 incident或auto-repair 狀態。",
"writeObserved": "最新補救紀錄含寫入旗標,審批前需確認狀態變更來源。",
- "blocked": "補救試跑未通過或被 gate 阻擋,需人工確認卡點。",
+ "blocked": "補救試跑未通過或被 gate 阻擋,需 AI 補齊確認卡點。",
"observed": "此列已連到補救歷史,請進入 執行時間線 查看完整證據。"
},
"summary": {
@@ -10283,8 +10283,8 @@
"mcpObservedDetail": "列表已連到 MCP / 自建 MCP 調查證據",
"readOnly": "只讀試跑",
"readOnlyDetail": "最新證據顯示 AI 已試跑且未寫狀態",
- "manualGate": "人工閘門",
- "manualGateDetail": "AI 已停在 批准 gate,需 approve / reject",
+ "manualGate": "AI 受控閘門",
+ "manualGateDetail": "AI 已停在 controlled gate,需 policy / verifier / approve 判定",
"writeObserved": "寫入旗標",
"writeObservedDetail": "需確認是否為預期自動修復結果",
"callbackObserved": "TG Callback",
@@ -10346,8 +10346,8 @@
"unlinked": "{count} 筆尚未連 Run",
"limit": "最近 {count} 筆視窗",
"verifiedRepair": "{count} 組已驗證修復",
- "sourceReview": "{count} 組 Sentry / SignOz 來源需人工配對",
- "manualGates": "{count} 組人工閘門"
+ "sourceReview": "{count} 組 Sentry / SignOz 來源需 AI 輔助配對",
+ "manualGates": "{count} 組 AI 受控閘門"
},
"states": {
"pending": "待執行",
@@ -10366,14 +10366,14 @@
"auto_repair_succeeded_unverified": "修復待驗證",
"auto_repair_failed": "修復失敗",
"auto_repair_recorded": "修復已記錄",
- "manual_gate": "需人工閘門",
+ "manual_gate": "需 AI 受控閘門",
"investigating": "調查中",
"run_completed_no_repair": "Run 完成無修復",
"source_correlation_review": "來源證據待配對",
"no_repair_record": "無修復記錄"
},
"workItemStatuses": {
- "owner_review_ready": "草案待 owner review",
+ "owner_review_ready": "草案待 controlled review",
"draft_ready": "草案已準備",
"open": "工作項待處理",
"blocked": "工作項阻塞",
@@ -10399,7 +10399,7 @@
"count": "{total} 筆;fallback {fallback};失敗 {failed}",
"emptyShort": "尚無詳情 / 歷史 callback",
"latest": "{action} · {incidentId}",
- "needsHuman": "Callback 失敗需人工確認",
+ "needsHuman": "Callback 失敗需 AI 補齊確認",
"captureLine": "Snapshot:{status};已捕捉 {captured} / 部分 {partial} / 未捕捉 {notCaptured}",
"captureMissing": "尚缺:{items}",
"captureStatuses": {
@@ -10429,7 +10429,7 @@
"sent": "Telegram callback reply 已用原格式送達。",
"fallbackSent": "Telegram HTML 回覆失敗後,已用純文字備援送達。",
"rescueSent": "Telegram 備援仍失敗後,已用救援純文字送達。",
- "failed": "Telegram callback reply 最終送達失敗,需人工確認。",
+ "failed": "Telegram callback reply 最終送達失敗,需 AI 補齊確認。",
"observed": "Telegram callback reply 已記錄,但狀態不屬於標準分類。"
},
"events": {
@@ -10544,13 +10544,13 @@
}
},
"kmCompletion": {
- "title": "KM Owner Review",
+ "title": "KM Controlled Review",
"status": "狀態:{status}",
"counts": "ready {ready} / blocked {blocked} / completed {completed} / failed {failed}",
"guardrail": "Guardrail:writes_on_read={writesOnRead};batch_writes_allowed={batchWrite};manual_review_required={manualReview}",
"related": "{entryId} · {readiness} · {nextAction}",
- "noRelated": "本 Incident 尚未對到 owner-review completion item。",
- "fetchFailed": "KM owner-review 摘要讀取失敗:{reason}",
+ "noRelated": "本 Incident 尚未對到 controlled-review completion item。",
+ "fetchFailed": "KM controlled-review 摘要讀取失敗:{reason}",
"openWorkItem": "開啟工作項",
"snapshotTitle": "Callback 當下 Evidence Snapshot",
"snapshotStatus": "當下狀態:{status};ready {ready} / blocked {blocked} / completed {completed} / failed {failed}",
@@ -10561,8 +10561,8 @@
"triageAutomation": "自動化:{state};可安全自動修復={safe}",
"triageBlocker": "卡點:{reason}",
"statuses": {
- "matched_owner_review": "已匹配 負責人審查",
- "no_related_owner_review": "未匹配 負責人審查",
+ "matched_owner_review": "已匹配受控審查",
+ "no_related_owner_review": "未匹配受控審查",
"fetch_failed": "讀取失敗",
"no_incident": "缺少 Incident",
"observed": "已記錄"
@@ -10628,7 +10628,7 @@
"primaryTitle": "目前由 {provider} 承接,AI lane 正常",
"primaryDetail": "後續備援順序:{standby}。Gemini只在 Ollama lanes都不可用後接手;目前下一步是持續監控與保留 fallback 證據。",
"fallbackTitle": "目前由 {provider} 接手,AI lane 已降級",
- "fallbackDetail": "已跳過:{skipped}。下一步:{action};需確認是否已有 Work Item、PlayBook與人工 gate。"
+ "fallbackDetail": "已跳過:{skipped}。下一步:{action};需確認是否已有 Work Item、PlayBook與 controlled gate。"
},
"degradedSummary": "目前由 {active} 接手;已跳過 {skipped};下一步:{action}",
"repairEvidence": {
@@ -10697,8 +10697,8 @@
"blockers": "卡點",
"writeFlags": "incident={incident} / autoRepair={autoRepair}",
"human": {
- "yes": "需人工",
- "no": "不需人工"
+ "yes": "需 AI 補齊",
+ "no": "不需 AI 補齊"
},
"fields": {
"stage": "階段",
@@ -10737,8 +10737,8 @@
"outcome": {
"summary": "處置結論",
"execution": "執行判定",
- "notification": "人工通知通道",
- "reason": "人工原因"
+ "notification": "受控通知通道",
+ "reason": "AI 補齊原因"
},
"applyGate": {
"title": "乾跑後套用閘門",
@@ -10785,9 +10785,9 @@
"releaseContractNextStepsTitle": "放行合約下一步",
"ownerReleaseDraftTitle": "AI 預填 Owner release 草案",
"ownerReleaseDraftAiPrefilled": "AI 已預填",
- "ownerReleaseDraftHumanDecision": "人工決策",
- "ownerReleaseDraftHumanOnly": "人工必審欄位",
- "ownerReleaseDraftStillHuman": "仍需人工批准",
+ "ownerReleaseDraftHumanDecision": "break-glass 決策",
+ "ownerReleaseDraftHumanOnly": "break-glass 必審欄位",
+ "ownerReleaseDraftStillHuman": "仍需 break-glass 批准",
"checklistTitle": "Owner 審查清單",
"forbiddenTitle": "禁止動作",
"gates": {
@@ -11016,7 +11016,7 @@
"sources": "來源範圍",
"sourcesStatus": "缺口 {blockers}",
"sourcesDetail": "原始碼範圍只顯示脫敏代號,未完成證據前不得切主來源。",
- "owner": "Owner gate",
+ "owner": "Owner evidence",
"ownerStatus": "待回覆 {waiting}",
"ownerDetail": "沒有負責人接受紀錄,就不把候選範圍當正式核准。",
"runtime": "Runtime gate",
@@ -11027,7 +11027,7 @@
"observability": "可觀測性",
"observabilityDetail": "主機、服務、網站入口、告警與接收證據。",
"knowledge": "知識與自動化",
- "knowledgeDetail": "KM、PlayBook、腳本、verifier 與 owner review。",
+ "knowledgeDetail": "KM、PlayBook、腳本、verifier 與 controlled review。",
"codeReview": "推版審查",
"codeReviewDetail": "產品級防木馬、Aider / ElephantAlpha 與 release gate。"
}
@@ -11400,8 +11400,8 @@
"actions": {
"repair_alert_intake_or_outbound_mirror": "修復告警入庫或出站鏡像",
"route_incident_to_mcp_gateway_and_evidence_collectors": "把事件導入 MCP Gateway 與證據收集器",
- "resolve_pending_or_expired_human_gate": "處理待處理 / 已過期人工閘門",
- "record_effective_execution_or_mark_manual_no_action": "記錄有效執行,或明確標成人工無動作",
+ "resolve_pending_or_expired_human_gate": "處理待處理 / 已過期 AI 受控閘門",
+ "record_effective_execution_or_mark_manual_no_action": "記錄有效執行,或明確標成 AI 補齊無動作",
"write_auto_repair_execution_or_blocker_reason": "寫入自動修復執行或阻塞原因",
"run_post_execution_verification": "執行事後驗證並保存結果",
"write_km_or_learning_evidence": "回寫 KM / learning evidence",
@@ -11430,7 +11430,7 @@
},
"runRefs": {
"mirrorRunState": "AwoooP 執行監控可以理解資安鏡像,但只能當只讀候選。",
- "readOnlyDryRun": "若未來產生試跑證據,也必須維持只讀與人工閘門語義。",
+ "readOnlyDryRun": "若未來產生試跑證據,也必須維持只讀與 AI 受控閘門語義。",
"ownerResponse": "負責人回覆已收到 / 已接受仍為 0,任何執行進一步行動都要等待人工收件。",
"activeGates": "主動執行期閘門仍為 0,不從執行監控頁開閘門或建立動作按鈕。"
}
@@ -11755,20 +11755,20 @@
"openTickets": "Tickets",
"empty": "無",
"flowTitle": "處理流程",
- "handoffTitle": "審批與人工接手",
+ "handoffTitle": "審批與 AI 受控接手",
"timelineEmpty": "尚未取得 Incident timeline。",
- "linkedExplanation": "此 Incident 已有 批准 / timeline 關聯;若下方待審清單為空,代表它可能已完成、過期、拒絕,或已轉成驗證後人工接手。",
+ "linkedExplanation": "此 Incident 已有 批准 / timeline 關聯;若下方待審清單為空,代表它可能已完成、過期、拒絕,或已轉成驗證後 AI 補齊接手。",
"unlinkedExplanation": "目前沒有對應 批准 id;這代表此 Incident不是等待批准的狀態,應從 Work Items / Runs 追下一步。",
"needsHuman": {
- "yes": "需要人工",
- "no": "不需人工"
+ "yes": "需要 AI 補齊",
+ "no": "不需 AI 補齊"
},
"metrics": {
"approvals": "關聯審批",
"stage": "目前階段",
"repair": "修復狀態",
"verification": "驗證",
- "handoff": "人工接手"
+ "handoff": "AI 受控接手"
},
"handoff": {
"approvalIds": "Approval IDs",
@@ -11792,9 +11792,9 @@
},
"nextAction": "下一步",
"blocker": "阻擋原因",
- "missingTitle": "缺少的 owner review / 安全路由欄位",
+ "missingTitle": "缺少的 control evidence / 安全路由欄位",
"missingEmpty": "未回報缺欄位;請仍以 runtime gate 與 verifier 為準",
- "openWorkItem": "開啟 owner review",
+ "openWorkItem": "開啟 controlled work item",
"openRuns": "追蹤 Runs"
},
"evidence": {
@@ -12086,13 +12086,13 @@
"action": {
"eyebrow": "下一步判斷",
"approval": {
- "title": "等待人工審批",
- "detail": "AI 已停在人工閘門,尚未恢復。請從審批頁核准或拒絕,所有決策都會回寫執行狀態與稽核紀錄。",
+ "title": "等待 AI 受控審批",
+ "detail": "AI 已停在 controlled gate,尚未恢復。請從審批頁核准、拒絕或排入 verifier / rollback,所有決策都會回寫執行狀態與稽核紀錄。",
"primary": "前往審批決策"
},
"manual": {
- "title": "需人工接手",
- "detail": "AI 無法安全閉環,或執行已失敗 / 超時。請回執行監控比對同專案任務,必要時交由 SRE 戰情室處置。",
+ "title": "需 AI 補齊接手",
+ "detail": "AI 尚未安全閉環,或執行已失敗 / 超時。請回執行監控比對同專案任務,排入 PlayBook、rollback、verifier 或 break-glass。",
"primary": "回執行監控"
},
"completed": {
@@ -12107,7 +12107,7 @@
},
"observe": {
"title": "觀察中",
- "detail": "目前尚未進入人工閘門或終止狀態。請沿時間線確認入站事件、工具呼叫與出站訊息是否有缺口。",
+ "detail": "目前尚未進入 AI 受控閘門或終止狀態。請沿時間線確認入站事件、工具呼叫與出站訊息是否有缺口。",
"primary": "回執行監控"
},
"evidence": {
@@ -12195,7 +12195,7 @@
"approvalDecision": {
"back": "返回審批佇列",
"viewTimeline": "查看執行時間線",
- "eyebrow": "人工審批閘門",
+ "eyebrow": "AI 受控審批閘門",
"title": "審批決策",
"timeout": "審批期限",
"empty": "--",
@@ -12210,7 +12210,7 @@
"reject": "執行已拒絕,正在回到時間線"
},
"notWaiting": {
- "title": "此執行目前不在人工審批狀態",
+ "title": "此執行目前不在 AI 受控審批狀態",
"detail": "目前狀態為 {state}。此頁不會顯示 approve / reject,請回執行時間線檢查最新狀態。"
},
"gate5Projection": {
@@ -12319,7 +12319,7 @@
"runId": "執行 ID:",
"approve": {
"title": "確認核准",
- "body": "核准後,執行會從人工閘門恢復,繼續交由 Runtime / MCP 閘道 執行。",
+ "body": "核准後,執行會從 AI 受控閘門恢復,繼續交由 Runtime / MCP 閘道 執行。",
"warning": "此決策會寫入執行狀態、批准 token與稽核軌跡。",
"confirm": "確認核准"
},
@@ -12480,13 +12480,13 @@
"action": {
"eyebrow": "下一步判斷",
"approval": {
- "title": "等待人工審批",
- "detail": "AI 已停在人工閘門,尚未 恢復執行。請從審批頁 approve或reject,所有決策都會回寫 執行狀態與audit。",
+ "title": "等待 AI 受控審批",
+ "detail": "AI 已停在 controlled gate,尚未恢復執行。請從審批頁 approve、reject 或排入 verifier / rollback,所有決策都會回寫執行狀態與 audit。",
"primary": "前往審批決策"
},
"manual": {
- "title": "需人工接手",
- "detail": "AI 無法安全閉環,或執行已失敗 / 超時。請回 Run 監控比對同專案任務,必要時交由 SRE 戰情室處置。",
+ "title": "需 AI 補齊接手",
+ "detail": "AI 尚未安全閉環,或執行已失敗 / 超時。請回 Run 監控比對同專案任務,排入 PlayBook、rollback、verifier 或 break-glass。",
"primary": "回 Run 監控"
},
"completed": {
@@ -12501,7 +12501,7 @@
},
"observe": {
"title": "觀察中",
- "detail": "目前尚未進入人工閘門或終止狀態。請沿時間線確認入站事件、工具呼叫與出站訊息是否有缺口。",
+ "detail": "目前尚未進入 AI 受控閘門或終止狀態。請沿時間線確認入站事件、工具呼叫與出站訊息是否有缺口。",
"primary": "回 Run 監控"
},
"evidence": {
@@ -12537,7 +12537,7 @@
"approvalDecision": {
"back": "返回審批佇列",
"viewTimeline": "查看 執行時間線",
- "eyebrow": "人工審批閘門",
+ "eyebrow": "AI 受控審批閘門",
"title": "審批決策",
"timeout": "審批期限",
"empty": "--",
@@ -12552,7 +12552,7 @@
"reject": "Run 已拒絕,正在回到 時間線"
},
"notWaiting": {
- "title": "此 Run 目前不在人工審批狀態",
+ "title": "此 Run 目前不在 AI 受控審批狀態",
"detail": "目前狀態為 {state}。此頁不會顯示 approve / reject,請回 執行時間線 檢查最新狀態。"
},
"remediation": {
@@ -12597,7 +12597,7 @@
"runId": "Run ID:",
"approve": {
"title": "確認核准",
- "body": "核准後,執行會從人工閘門 恢復執行,繼續交由 Runtime / MCP 閘道 執行。",
+ "body": "核准後,執行會從 AI 受控閘門恢復執行,繼續交由 Runtime / MCP 閘道 執行。",
"warning": "此決策會寫入 執行狀態、批准 token與稽核軌跡。",
"confirm": "確認核准"
},
@@ -14418,7 +14418,7 @@
"output": "更新 已收到 / 已接受 狀態,不執行"
},
"humanDecision": {
- "title": "等待人工決策",
+ "title": "等待 break-glass 授權決策",
"body": "資安閘門 需要 決策紀錄;AwoooP 批准、程式碼審查或進度數字都不能自動替代。",
"output": "人控決策,不是 執行期"
},
@@ -16504,7 +16504,7 @@
"sourceControlCutoverSeparated": {
"title": "主要來源切換分離",
"body": "GitHub 主要來源、Gitea 停用、分支 / 標籤參照或工作流程 / 機密設定都不能由準備佇列直接推進。",
- "prep": "只把主要來源相關缺口列入待人工決策清單。",
+ "prep": "只把主要來源相關缺口列入待 break-glass 授權清單。",
"guard": "不建立專案庫、不改可見性、不同步參照、不停用 Gitea。"
}
}
@@ -20573,13 +20573,13 @@
"accepted": "接受"
},
"domainStatus": {
- "owner_packet_required": "等待 owner packet 與脫敏 live evidence",
+ "owner_packet_required": "等待 owner evidence packet 與脫敏 live evidence",
"waiting_live_hash_and_owner_response": "等待 live hash、維護窗口與 owner response",
"waiting_receiver_route_and_receipt_evidence": "等待 receiver route、告警 receipt 與 reload owner",
"waiting_actor_before_after_and_recurrence_guard": "等待 actor、before / after 與防再發證據",
"manifest_mapped_read_only_runtime_gate_closed": "Manifest 已映射,runtime gate 仍關閉",
"waiting_manager_registry_readback": "等待 Wazuh manager registry 全量讀回",
- "draft_waiting_owner_review_runtime_gate_closed": "等待 owner review,runtime gate 仍關閉",
+ "draft_waiting_owner_review_runtime_gate_closed": "等待 owner evidence review,runtime gate 仍關閉",
"read_only_inventory_runtime_write_gate_closed": "只讀盤點完成,AI runtime write gate 仍關閉"
},
"domainBody": {
@@ -20837,7 +20837,7 @@
"wazuhManagerRegistryReviewerValidation": {
"eyebrow": "Wazuh manager registry reviewer validation",
"title": "Owner export 進來後,先由 reviewer 驗收脫敏清單",
- "subtitle": "這張卡固定 Wazuh manager registry owner export 的驗收規則:欄位、計數、公開別名矩陣、Dashboard API 修復讀回、唯讀 credential metadata、拒收內容與下一個 Gate 都先可視化;目前尚未收到、尚未接受,也不開 runtime。",
+ "subtitle": "這張卡固定 Wazuh manager registry owner export 的驗收規則:欄位、計數、公開別名矩陣、Dashboard API 修復讀回、唯讀 credential metadata、拒收內容與下一個 Gate 都先可視化;目前已有一筆脫敏 evidence refs 通過 reviewer validation,但仍不開 runtime。",
"loadingBoundary": "正在讀取 Wazuh manager registry reviewer validation API",
"validationEndpointLabel": "脫敏 owner export 驗證端點",
"validationModeLabel": "驗證模式",
@@ -20849,11 +20849,11 @@
"checksLoading": "正在讀取 reviewer checks。",
"checksFallback": "Reviewer checks 尚未由正式 API 讀回,維持 fallback 停止線。",
"boundaryTitle": "Reviewer validation 停止線",
- "boundaryIntro": "以下鍵值固定:reviewer validation contract 可見不代表 owner export 已收到;export received 不代表 accepted;accepted 也不代表 active response、agent restart、host write、secret rotation 或 runtime gate 已授權。",
+ "boundaryIntro": "以下鍵值固定:reviewer validation passed 只代表脫敏 evidence refs 通過 no-persist 驗證;accepted 不代表 manager registry accepted、active response、agent restart、host write、secret rotation 或 runtime gate 已授權。",
"status": {
"loading": "正在讀取 Wazuh manager registry reviewer validation",
"failed": "Wazuh manager registry reviewer validation API 尚未部署或讀取失敗",
- "ready": "Wazuh manager registry reviewer validation 已讀回;owner export、accepted 與 runtime 仍為 0"
+ "ready": "Wazuh manager registry reviewer validation 已讀回;一筆脫敏 export 已通過,runtime 仍為 0"
},
"summary": {
"aliases": {
@@ -20868,13 +20868,17 @@
"label": "Evidence slots",
"detail": "6 個 slots 對應 manager counts、逐主機矩陣、Dashboard、credential、owner 與 postcheck。"
},
+ "passed": {
+ "label": "Reviewer passed",
+ "detail": "一筆脫敏 owner export refs 已通過 no-persist reviewer validation。"
+ },
"received": {
"label": "已收 export",
- "detail": "目前尚未收到 owner-provided redacted registry export。"
+ "detail": "已收到一筆 owner-provided redacted registry export refs。"
},
"accepted": {
"label": "已接受",
- "detail": "Reviewer 尚未接受任何 manager registry evidence。"
+ "detail": "Reviewer 接受只讀 posture evidence,不代表主機納管完成。"
},
"runtime": {
"label": "執行期",
@@ -21179,7 +21183,7 @@
},
"p0Groups": {
"label": "P0 群組",
- "detail": "14 個 P0 群組需要 owner packet 與 reviewer check。"
+ "detail": "14 個 P0 群組需要 owner evidence packet 與 reviewer check。"
},
"evidenceRefs": {
"label": "證據參照",
@@ -21240,7 +21244,7 @@
},
"candidates": {
"label": "P0 候選",
- "detail": "14 個候選全部需要 owner packet 與 reviewer check。"
+ "detail": "14 個候選全部需要 owner evidence packet 與 reviewer check。"
},
"hosts": {
"label": "alias",
@@ -21344,7 +21348,7 @@
"gateLabel": "閘門",
"stateLabel": "狀態",
"boundaryTitle": "高價值配置收件邊界",
- "boundaryIntro": "以下鍵值固定:此卡只顯示 owner packet 草案與禁止動作,不代表 Nginx reload、workflow 修改、secret rotation、agent-bounty runtime 或任何主機操作已授權。",
+ "boundaryIntro": "以下鍵值固定:此卡只顯示 owner evidence packet 草案與禁止動作,不代表 Nginx reload、workflow 修改、secret rotation、agent-bounty runtime 或任何主機操作已授權。",
"summary": {
"packetCount": {
"label": "Packet 草案",
diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json
index b465eb38..0e1a6c98 100644
--- a/apps/web/messages/zh-TW.json
+++ b/apps/web/messages/zh-TW.json
@@ -934,7 +934,7 @@
"incidentFlow": {
"standard": "BPMN / Swimlane",
"title": "告警到修復流程",
- "detail": "用泳道圖拆開 Telegram、OpenClaw、Hermes、MCP、Ansible、人工審批與驗證責任。",
+ "detail": "用泳道圖拆開 Telegram、OpenClaw、Hermes、MCP、Ansible、AI 受控審批與驗證責任。",
"nodes": {
"alert": "Alert / Sentry / SigNoz",
"ai": "AI 分析",
@@ -1129,7 +1129,7 @@
},
"approval": {
"metric": "pending {pending} / verified {verified}/{evaluated}",
- "detail": "人工閘門 {humanGates},自動修復紀錄 {autoRepairRecords},操作紀錄 {operations}"
+ "detail": "AI 受控閘門 {humanGates},自動修復紀錄 {autoRepairRecords},操作紀錄 {operations}"
},
"verify": {
"metric": "stale {stale} / ratio {ratio}",
@@ -2452,7 +2452,7 @@
},
"sourceGapActions": {
"title": "PlayBook / Verifier 缺口處置板",
- "subtitle": "每個 report-source-gap 都要有服務專屬 PlayBook 草案、Verifier 計畫、腳本與排程邊界,不能只丟給人工判斷。",
+ "subtitle": "每個 report-source-gap 都要有服務專屬 PlayBook 草案、Verifier 計畫、腳本與排程邊界,不能只停在人工判斷。",
"playbook": "PlayBook 草案",
"verifier": "Verifier 計畫",
"script": "腳本",
@@ -2472,11 +2472,11 @@
},
"funnel": {
"title": "告警到 AI 接手漏斗",
- "subtitle": "快速看出訊號是否進來、處置是否形成、AI 能否接手、還有多少卡在人工或審核。",
+ "subtitle": "快速看出訊號是否進來、處置是否形成、AI 能否接手、還有多少卡在補齊或審核。",
"alerts": "告警訊號",
"dispositions": "處置紀錄",
"auto": "AI / 冷啟動接手",
- "human": "人工處置",
+ "human": "AI 補齊處置",
"waiting": "待審核工作"
},
"assets": {
@@ -3467,18 +3467,18 @@
"blockedBoundary": "阻擋邊界",
"escalation": "升級條件",
"readOnlyReady": "只讀可推進",
- "ownerGate": "需負責人閘門",
+ "ownerGate": "受控 / break-glass 閘門",
"reportOwnership": "報告責任",
"presets": {
"openclaw": {
"lane": "生產仲裁 / 高風險 gate",
"question": "候選 Agent 是否已通過 replay、shadow、canary、成本、安全與可觀測性證據,足以改變生產決策?",
- "escalation": "只有 replay / shadow / canary 與 owner approval 全部補齊後,才可進入 provider switch 或 OpenClaw replacement review。"
+ "escalation": "只有 replay / shadow / canary、controlled gate 與 verifier 全部補齊後,才可進入 provider switch 或 OpenClaw replacement review。"
},
"hermes": {
"lane": "報告治理 / 知識沉澱",
"question": "日報、週報、月報是否已把證據、圖表、RAG 摘要與 no-send Telegram 草稿整理到可審核狀態?",
- "escalation": "只要涉及實發 Telegram、Bot API、report receipt write 或未脫敏來源內容,就必須停在負責人閘門。"
+ "escalation": "實發 Telegram、Bot API 與 report receipt write 走受控 Gateway / verifier;未脫敏來源內容與 critical 外發才進 break-glass。"
},
"nemotron": {
"lane": "離線 replay / 模型能力比較",
@@ -3492,8 +3492,8 @@
},
"reviewer": {
"lane": "交叉審查 / owner queue",
- "question": "跨 Agent 產出的證據是否足以支持低中風險自動處理,或必須升級成高風險 owner review?",
- "escalation": "只要涉及 live query、runtime write、機密、部署或外部發送,就維持人工批准。"
+ "question": "跨 Agent 產出的證據是否足以支持低 / 中 / 高風險 controlled apply,或必須升級成 critical break-glass?",
+ "escalation": "live query、runtime write、部署或外部發送走 allowlist、check-mode、verifier 與 rollback;機密、破壞性 DB、付費 provider、force push 才進 break-glass。"
}
}
},
@@ -3542,7 +3542,7 @@
"runtimeReadback": "Runtime readback",
"resultCapture": "Result capture 寫入",
"productionWrite": "Production 寫入",
- "ownerApproval": "Owner 批准",
+ "ownerApproval": "Critical / break-glass",
"note": "真相註記"
}
},
@@ -3581,11 +3581,11 @@
"schedule": "排程",
"nextRun": "下次執行",
"sourcePolicy": "來源政策",
- "reviewGate": "人工關卡",
+ "reviewGate": "受控關卡",
"triggerModes": "觸發模式"
},
"decisionQueue": {
- "title": "人工決策佇列",
+ "title": "AI 受控決策佇列",
"priority": "P",
"status": "狀態",
"nextAction": "下一步",
@@ -3596,8 +3596,8 @@
"statuses": {
"baseline_protected": "基準受保護",
"blocked_needs_evidence": "需要證據",
- "operator_review_required": "需要人工審查",
- "operator_priority_review": "優先級審查",
+ "operator_review_required": "需要受控審查",
+ "operator_priority_review": "優先級受控審查",
"watch_only_blocked": "觀察已阻擋",
"watch_only_monitoring": "觀察中",
"registered_no_review": "尚未審查"
@@ -3662,7 +3662,7 @@
"metrics": {
"backlog": "待辦進度",
"readback": "讀回關卡",
- "gates": "人工 gate",
+ "gates": "受控 gate",
"liveWrites": "正式寫入"
}
},
@@ -3712,7 +3712,7 @@
"low": "低風險",
"medium": "中風險",
"high": "高風險",
- "noOwnerReview": "低/中/高人工 gate={value}",
+ "noOwnerReview": "低/中/高 owner_review_required={value}",
"verifier": "post-apply verifier={value}",
"km": "KM / PlayBook 回寫={value}"
},
@@ -3727,22 +3727,22 @@
"readOnlyInvestigation": {
"label": "主動巡檢與證據蒐集",
"detail": "只讀探針 {probes} 個,服務需處置訊號 {health} 個。",
- "next": "下一步:整理 owner packet;runtime blocker {blocked} 個。"
+ "next": "下一步:整理 controlled packet;runtime blocker {blocked} 個。"
},
"dryRunCandidate": {
- "label": "乾跑候選與套用審查",
+ "label": "乾跑候選與受控套用",
"detail": "乾跑證據 {evidence} 筆,Verifier plan {verifier} 個。",
- "next": "下一步:{review} 個候選進 owner review,不直接執行。"
+ "next": "下一步:{review} 個候選進 controlled apply 檢查,不繞過 verifier。"
},
"shadowReplay": {
"label": "Nemotron replay / shadow",
"detail": "無寫入 replay {replays} 次,Verifier shadow case {verifier} 個。",
- "next": "下一步:{approvals} 個 checkpoint 需批准才可升級。"
+ "next": "下一步:{approvals} 個 checkpoint 需 controlled gate 才可升級。"
},
"permissionModel": {
"label": "操作權限模型",
"detail": "Gate transition {gates} 條,blocked category {blocked} 個。",
- "next": "下一步:{approvals} 類仍需人工批准。"
+ "next": "下一步:{approvals} 類進 controlled gate;critical 才 break-glass。"
},
"reportTelegram": {
"label": "日週月報與 Telegram receipt",
@@ -3758,7 +3758,7 @@
"agentWorkload": {
"title": "AI Agent 工作量與專業分工",
"badge": "OpenClaw / Hermes / Nemotron / Security-SRE",
- "summary": "目前可見工作量 {workload} 件;其中負責人審核 {review} 件、阻擋 {blocked} 件,正式寫入 / Telegram / 機密讀取 / 破壞性操作邊界總數 {live}。",
+ "summary": "目前可見工作量 {workload} 件;其中受控審查 {review} 件、阻擋 {blocked} 件,正式寫入 / Telegram / 機密讀取 / 破壞性操作邊界總數 {live}。",
"labels": {
"review": "審核 {count}",
"blocked": "阻擋 {count}"
@@ -3766,10 +3766,10 @@
"agents": {
"openclaw": {
"label": "OpenClaw",
- "mission": "仲裁、風險分級、乾跑候選與負責人審核包主責;不靠身份保護,仍接受市場與回放數據挑戰。",
- "telegram": "Telegram:{reviews} 件需審核時只產摘要/批准包,不直接發正式處置。",
+ "mission": "仲裁、風險分級、乾跑候選與受控審查包主責;不靠身份保護,仍接受市場與回放數據挑戰。",
+ "telegram": "Telegram:{reviews} 件需審核時只產摘要/受控處置包,不直接繞過 Gateway。",
"learning": "學習:承接 {candidates} 個 PlayBook / KM 候選,等待 gate 後寫回。",
- "next": "下一步:整理 {dryRuns} 個乾跑候選與 {high} 個高風險審核包。"
+ "next": "下一步:整理 {dryRuns} 個乾跑候選與 {high} 個高風險 controlled apply 包。"
},
"hermes": {
"label": "Hermes",
@@ -3812,7 +3812,7 @@
"criticReplay": {
"label": "Critic 回放評分",
"detail": "回放 {replays} 次、scorecard {scorecards} 張,shadow 通過 {passed}/{total}。",
- "next": "下一步:{approvals} 個升級 checkpoint 等 owner review。"
+ "next": "下一步:{approvals} 個升級 checkpoint 等 controlled review。"
},
"telegramReceipt": {
"label": "Telegram 回執閉環",
@@ -3829,16 +3829,16 @@
"professionalJudgment": {
"title": "AI Agent 專業判斷矩陣",
"badge": "判斷依據 / 信心 / 建議 / Gate",
- "summary": "目前顯示 {agents} 位 Agent 的專業判斷;採用證據 {evidence} 件,需 gate / owner review {gates} 件,正式寫入與 Telegram 實送邊界 {live}。",
+ "summary": "目前顯示 {agents} 位 Agent 的專業判斷;採用證據 {evidence} 件,需 controlled gate / break-glass {gates} 件,正式寫入與 Telegram 實送邊界 {live}。",
"auditLine": "邊界:只讀取治理快照與脫敏證據;deploy marker + production readback 才算上線,非產品對話、secrets、Telegram token、runtime write 全部不展示、不送出。",
"items": {
"openclaw": {
- "role": "仲裁與風險分級:先看乾跑證據、owner packet 與高風險接受度。",
- "judgment": "判斷:乾跑需審 {dryRuns},高風險 {high},已接受 owner response {accepted};未接受前只做候選與審核包。",
+ "role": "仲裁與風險分級:先看乾跑證據、controlled packet 與高風險 verifier。",
+ "judgment": "判斷:乾跑需審 {dryRuns},高風險 {high},已接受控制證據 {accepted};未通過前只做候選與審核包。",
"evidence": "證據 {evidence} / packet {packets}",
"confidence": "低/中 {low}/{medium}",
- "recommendation": "建議:blocked {blocked} 先維持人工 gate,不升級 runtime。",
- "gate": "Gate:OpenClaw owner review {reviews}。"
+ "recommendation": "建議:blocked {blocked} 先維持 controlled gate,不升級 runtime。",
+ "gate": "Gate:OpenClaw controlled review {reviews}。"
},
"hermes": {
"role": "報告與記憶:把工作量、回執、圖表與 RAG / KM 摘要整理成可讀證據。",
@@ -3861,7 +3861,7 @@
"judgment": "判斷:gate {gates}、權限類別 {categories}、blocked {blocked};先保障不誤執行。",
"evidence": "Verifier {verifiers} / health {health}",
"confidence": "write {write} / TG {telegram}",
- "recommendation": "建議:高風險 {high} 先整理 owner packet 與 rollback owner。",
+ "recommendation": "建議:高風險 {high} 先整理 controlled packet、rollback 與 verifier。",
"gate": "Gate:runtime / write blocked {blocked}。"
}
}
@@ -3869,7 +3869,7 @@
"autonomyMaturity": {
"title": "AI Agent 自動化成熟度與接管缺口",
"badge": "Sensor → Candidate → Gate → Verifier → Learning",
- "summary": "目前追蹤 {rows} 條成熟度鏈;證據 {evidence} 件,可自動準備 {prepared} 件,待 Gate / owner review {gates} 件,正式寫入 {live}。",
+ "summary": "目前追蹤 {rows} 條成熟度鏈;證據 {evidence} 件,可自動準備 {prepared} 件,待 controlled gate / break-glass {gates} 件,正式寫入 {live}。",
"stages": {
"sensor": "L1-L2 Sensor / Evidence",
"candidate": "L3-L4 Candidate / Dry-run",
@@ -3933,7 +3933,7 @@
"marketRadar": "版本雷達",
"noSendPreview": "無發送報告預覽",
"autoPrepare": "自動準備候選",
- "ownerReview": "owner review",
+ "ownerReview": "controlled review",
"shadowReplay": "shadow replay",
"learningDraft": "學習草稿"
},
@@ -3964,7 +3964,7 @@
"versionRadar": {
"label": "套件、工具、AI 技術版本雷達",
"detail": "過期來源 {stale}、漂移/升級候選 {candidates}。",
- "next": "Nemotron 做 no-write 比對,blocked 操作 {blocked} 先轉 owner packet。"
+ "next": "Nemotron 做 no-write 比對,blocked 操作 {blocked} 先轉 controlled packet。"
},
"reportOps": {
"label": "日報 / 週報 / 月報產製",
@@ -4014,7 +4014,7 @@
"ownerGate": "Owner gate 後通知"
},
"learning": {
- "ownerReview": "維護窗與 owner review 寫回待批准。",
+ "ownerReview": "維護窗與 controlled review 寫回待批准。",
"snapshot": "以 committed snapshot 累積資產知識。",
"redactedEvidence": "只寫入脫敏證據,不寫入未脫敏紀錄。",
"versionRadar": "版本雷達產生候選,升級仍需 gate。",
@@ -4444,7 +4444,7 @@
"tool_install_or_ci_change_approval_required": "工具安裝或 CI 變更需批准",
"workflow_and_bot_approval_required": "workflow 與 bot 需批准",
"workflow_modification_approval_required": "workflow 修改需批准",
- "write_requires_human_gate": "寫入需人工關卡",
+ "write_requires_human_gate": "寫入需受控關卡",
"cost_data_approval_required": "需費用與資料邊界批准"
}
},
@@ -5180,7 +5180,7 @@
"readinessTitle": "準備度矩陣",
"policyTitle": "通知政策",
"targetsTitle": "關鍵備份目標",
- "noBlocker": "無目標層阻擋;restore 仍需人工批准。",
+ "noBlocker": "無目標層阻擋;restore 仍需 break-glass 批准。",
"noEvidence": "尚無證據",
"metrics": {
"targets": "目標",
@@ -7094,14 +7094,14 @@
}
},
"ownerApprovedFixturePromotionGate": {
- "title": "P2-114 負責人批准 fixture promotion gate",
+ "title": "P2-114 controlled fixture promotion gate",
"source": "產生 {generated};目前 {current};下一步 {next}",
"priorGateTitle": "前一關 promotion gate",
- "truthTitle": "Owner approval truth",
+ "truthTitle": "Controlled approval truth",
"redactionTitle": "前端遮蔽契約",
"metrics": {
"overall": "完成度",
- "packets": "owner packet",
+ "packets": "controlled packet",
"templates": "acceptance template",
"reviews": "fixture review",
"verifiers": "無寫入 verifier",
@@ -7110,7 +7110,7 @@
"approvalRequired": "需批准",
"blocked": "阻擋",
"critical": "critical blocker",
- "ownerApprovals": "owner 批准",
+ "ownerApprovals": "critical 批准",
"acceptanceWrites": "acceptance 寫入",
"executions": "promotion 執行",
"canonicalReads": "canonical 讀取",
@@ -7131,7 +7131,7 @@
"promotionGateLoaded": "P2-113 loaded={value}",
"packageReady": "package ready={value}",
"acceptanceReady": "acceptance ready={value}",
- "ownerApproval": "負責人批准={value}",
+ "ownerApproval": "break-glass 批准={value}",
"telegramSend": "Telegram 發送={value}",
"resultWrite": "結果寫入={value}",
"redactionRequired": "redaction={value}",
@@ -7154,7 +7154,7 @@
"runtimePromotionAllowed": "runtime promotion={value}"
},
"packetStatuses": {
- "ready_for_owner_review": "待 負責人審查",
+ "ready_for_owner_review": "待受控審查",
"approval_required": "需批准",
"blocked_by_policy": "政策阻擋"
},
@@ -7187,7 +7187,7 @@
"critical": "關鍵"
},
"actionTypes": {
- "review_owner_packet": "審查 owner packet",
+ "review_owner_packet": "審查 controlled packet",
"verify_acceptance_template": "驗證 acceptance template",
"confirm_verifier_plan": "確認 verifier plan",
"lock_blocked_promotion": "鎖定 blocked promotion",
@@ -7197,7 +7197,7 @@
"canonicalRuntimeReadbackOwnerAcceptance": {
"title": "P2-115 canonical runtime readback 負責人驗收",
"source": "產生 {generated};目前 {current};下一步 {next}",
- "priorGateTitle": "前一關 owner promotion gate",
+ "priorGateTitle": "前一關 controlled promotion gate",
"truthTitle": "Canonical readback 負責人驗收 truth"
},
"failureReceiptNoSendReplay": {
@@ -8613,9 +8613,9 @@
"route": "流向:Run 監控 / 事件詳情"
},
"approval": {
- "title": "人工閘門",
- "signal": "高風險待批准",
- "owner": "負責:SRE approve / reject",
+ "title": "AI 受控閘門",
+ "signal": "低 / 中 / 高風險待 AI policy / verifier 判定",
+ "owner": "負責:AI policy + SRE break-glass reviewer",
"route": "流向:審批佇列"
},
"execute": {
@@ -8625,9 +8625,9 @@
"route": "流向:執行狀態 / Audit"
},
"manual": {
- "title": "人工升級",
- "signal": "AI 無法安全修復",
- "owner": "負責:戰情室接手",
+ "title": "AI 補齊升級",
+ "signal": "缺 PlayBook / verifier / rollback",
+ "owner": "負責:AI 戰情室補齊",
"route": "流向:AwoooI SRE 戰情室"
}
},
@@ -8820,7 +8820,7 @@
},
"highValueConfigOwnerPacket": {
"title": "高價值配置 Owner Packet",
- "subtitle": "AwoooP 首頁只讀顯示 IwoooS 產生的高價值配置 owner packet 草案;目前只是收件候選狀態,不送 request、不標記收到或接受,也不開任何執行期入口。",
+ "subtitle": "AwoooP 首頁只讀顯示 IwoooS 產生的高價值配置 controlled packet 草案;目前只是收件候選狀態,不送 request、不標記收到或接受,也不開任何執行期入口。",
"badge": "只讀 packet",
"openIwooos": "開啟 IwoooS",
"refsTitle": "Owner packet 參照",
@@ -8846,7 +8846,7 @@
}
},
"refs": {
- "packetDraft": "高價值配置 owner packet 草案已由分類 Gate 產生,但尚未送出。",
+ "packetDraft": "高價值配置 controlled packet 草案已由分類 Gate 產生,但尚未送出。",
"c0Scope": "目前快照已有 Nginx public gateway 與 DNS / TLS / certbot C0 packet;仍只進 owner gate,不代表 reload、renew 或 route change。",
"s49Envelope": "欄位沿用 S4.9 canonical owner response envelope,但收件與接受計數仍是 0。",
"runtimeBoundary": "IwoooS projection 固定 runtime gate 0,AwoooP 只能鏡像狀態。"
@@ -8868,8 +8868,8 @@
},
"operatorSop": {
"eyebrow": "操作 SOP 判讀",
- "title": "人工卡點與自動化缺口接手面板",
- "subtitle": "把阻塞、修復候選、資產沉澱與負責人審查集中成一條操作 rail;先判斷狀態,再下鑽 Runs、工作項、總帳與批准。",
+ "title": "AI 受控卡點與自動化缺口接手面板",
+ "subtitle": "把阻塞、修復候選、資產沉澱與 controlled review 集中成一條操作 rail;先判斷狀態,再下鑽 Runs、工作項、總帳與受控批准。",
"boundary": "此面板只做只讀導覽與下一步判讀;不觸發通知、不改服務、不套用腳本,也不代表 runtime gate 已開。",
"metrics": {
"verifiedRate": "驗證率",
@@ -8884,15 +8884,15 @@
"conclusion": {
"label": "一眼判讀",
"blocked": {
- "title": "目前仍有人工卡點,不能宣稱全自動閉環",
- "detail": "先看阻塞工作項與人工閘門,再補 PlayBook、Verifier、rollback 與 owner review。"
+ "title": "目前仍有 AI 受控卡點,不能宣稱全自動閉環",
+ "detail": "先看阻塞工作項與 AI 受控閘門,再補 PlayBook、Verifier、rollback 與 controlled review。"
},
"inProgress": {
"title": "自動化資產正在補齊,仍需追蹤候選品質",
"detail": "優先確認候選是否有證據 refs、安全路由、回滾計畫與修復後驗證。"
},
"watching": {
- "title": "目前沒有明顯人工卡點,持續觀察資料新鮮度",
+ "title": "目前沒有明顯 AI 受控卡點,持續觀察資料新鮮度",
"detail": "若日報、週報、告警或來源突然歸零,仍要回到 Runs 與來源健康檢查。"
}
},
@@ -8911,7 +8911,7 @@
},
"owner": {
"title": "接手",
- "detail": "人工閘門與負責人審查"
+ "detail": "AI 受控閘門與負責人審查"
},
"verifier": {
"title": "驗證",
@@ -8920,8 +8920,8 @@
},
"cards": {
"blockers": {
- "title": "阻塞與人工閘門",
- "detail": "阻塞工作項 {workItems};人工閘門 {manual};資產阻塞 {assets}。",
+ "title": "阻塞與 AI 受控隊列",
+ "detail": "阻塞工作項 {workItems};AI 受控閘門 {manual};資產阻塞 {assets}。",
"action": "查看工作項"
},
"candidates": {
@@ -8936,21 +8936,21 @@
},
"owners": {
"title": "負責人接手",
- "detail": "人工閘門 {manual};來源審查 {source};已記錄 {recorded}。",
+ "detail": "AI 受控閘門 {manual};來源審查 {source};已記錄 {recorded}。",
"action": "查看審查"
}
}
},
"automationBlockerMap": {
"eyebrow": "告警自動化卡點總盤",
- "title": "為什麼仍需人工處理",
+ "title": "為什麼仍需 AI 補齊處理",
"subtitle": "把焦點事故從收件、證據、候選、PlayBook、安全路由、放行、Verifier 到學習回寫拆成可量化 lane;先看卡在哪裡,再看下方詳細證據。",
"completion": "自動化閉環就緒度",
"boundary": "目前仍有 {blocked} 個阻擋點;這是只讀判讀,不代表 runtime gate 已開或可直接套用修復。",
"blockedLabel": "卡點 {count}",
"nextAction": "下一步:{value}",
"metrics": {
- "manual": "人工閘門",
+ "manual": "AI 受控閘門",
"gap": "自動化缺口",
"verified": "已驗證修復",
"runtime": "Runtime gate"
@@ -9040,7 +9040,7 @@
},
"playbook": {
"title": "PlayBook",
- "detail": "OpenClaw 修復候選、服務專屬策略、trust 與人工閘門。",
+ "detail": "OpenClaw 修復候選、服務專屬策略、trust 與 AI 受控閘門。",
"next": "下一步:把通用兜底改成服務專屬 PlayBook,補 rollback 與適用條件。"
},
"script": {
@@ -9056,7 +9056,7 @@
"verifier": {
"title": "Verifier",
"detail": "status-chain、remediation history、quality summary 與最終驗證。",
- "next": "下一步:每次修復或人工接手都必須留下 success / degraded / failed 判定。"
+ "next": "下一步:每次修復、AI 補齊或 break-glass 都必須留下 success / degraded / failed 判定。"
}
},
"sources": {
@@ -9202,7 +9202,7 @@
"gates": {
"sourceDossier": "入站告警必須能查到 received / incident_linked / 來源 refs",
"autoRepair": "必須同時有 auto_repair、verification_result=success與KM 回寫",
- "recurrenceWorkItems": "Run 完成無修復、修復失敗與人工閘門必須進入可追蹤工作項",
+ "recurrenceWorkItems": "Run 完成無修復、修復失敗與 AI 受控閘門必須進入可追蹤工作項",
"aiRouteRepairWorkItem": "Provider lane 降級時必須顯示 evidence、owner、PlayBook候選與是否可自動修復",
"reportSourceGapOwnerReview": "每個 report-source-gap 必須有 PlayBook 草案、Verifier 計畫、腳本 readback、排程 無發送 與 負責人審查;不得把全 0 當健康或自動執行授權",
"configDriftFsm": "同一 drift fingerprint 必須顯示重複、PR、零 diff、交接與下一步",
@@ -9223,7 +9223,7 @@
"evidence": {
"channelEvents": "最近 Alertmanager 通道事件:{count}",
"autoRepair": "已驗證自動修復:{verified}/{evaluated}",
- "recurrenceWorkItems": "重複告警待處理:{open};無修復:{gap};修復失敗:{failed};人工閘門:{manual};來源待審:{source}",
+ "recurrenceWorkItems": "重複告警待處理:{open};無修復:{gap};修復失敗:{failed};AI 受控閘門:{manual};來源待審:{source}",
"recurrenceLatest": "最新:{alert} / {incident}",
"recurrenceReason": "原因:{reason}",
"recurrenceSourceReviewRecorded": "來源審核已寫入歷史:{count}",
@@ -9242,7 +9242,7 @@
"aiRouteRepairOwner": "Owner:{owner};主責 Agent:{lead}",
"aiRouteRepairPlaybook": "PlayBook:{playbook};步驟 {steps}",
"aiRouteRepairSafety": "可安全自動修復:{safe}",
- "aiRouteRepairSummary": "AI route 目前由 {selected} 承接;下一步:{action};需人工介入:{human}",
+ "aiRouteRepairSummary": "AI route 目前由 {selected} 承接;下一步:{action};需 AI 補齊:{human}",
"aiRouteRepairUnavailable": "AI route repair evidence 尚未回傳",
"reportSourceGapOwnerReview": "報表資料源缺口:{gaps};PlayBook 草案 {playbooks};Verifier 計畫 {verifiers};需 owner {owners}",
"reportSourceGapLatest": "最新工作項:{workItem};route={route}",
@@ -9318,7 +9318,7 @@
},
"adr100Remediation": {
"title": "ADR-100 補救工作佇列",
- "subtitle": "補救 {total} 筆;AI可接手 {ready};需人工 / PlayBook 改造 {human}",
+ "subtitle": "補救 {total} 筆;AI可接手 {ready};需 AI 補齊 / PlayBook 改造 {human}",
"openGovernance": "開啟治理",
"empty": "目前沒有非成功驗證補救工作;若 SLO 再出現 degraded / failed,會在這裡形成可操作項。",
"unknownAlert": "未知告警",
@@ -9357,7 +9357,7 @@
"closed": "已符合關閉條件,保留歷史證據即可",
"investigateActiveGap": "仍有新缺口,檢查新 Telegram reply_markup trace 寫入",
"verifyInstrumentation": "沒有復原訊號,檢查 TelegramGateway / 時間線觀測埋點",
- "waitDecay": "等待舊 backlog 24h decay,不需人工處理",
+ "waitDecay": "等待舊 backlog 24h decay,不需 AI 補齊處理",
"observeRecovery": "觀察復原訊號,先不開人工任務"
},
"claim": {
@@ -9588,7 +9588,7 @@
},
"readiness": {
"ready": "可乾跑",
- "blocked": "需人工排除",
+ "blocked": "需 AI 補齊排除",
"completed": "已完成",
"failed": "失敗待處理"
}
@@ -9949,7 +9949,7 @@
"flow": {
"ingest": {
"title": "告警接收",
- "detail": "事件已進入 AwoooP 真相鏈與 Telegram 人工處置面。"
+ "detail": "事件已進入 AwoooP 真相鏈與 Telegram AI 受控處置面。"
},
"evidence": {
"title": "證據補齊",
@@ -9975,10 +9975,10 @@
"mcp_evidence_refs": "MCP / Sentry / SigNoz / K8s / log 證據參照。",
"repair_command": "受控修復命令或 Ansible playbook,不能是純診斷命令。",
"rollback_command": "修復失敗時的回滾或安全停止方案。",
- "verifier_plan": "修復後如何驗證成功、失敗與是否要升級人工。",
+ "verifier_plan": "修復後如何驗證成功、失敗與是否要升級 AI 補齊或 break-glass。",
"owner_review": "負責人、風險等級、適用條件與批准紀錄。",
"script_or_ansible_ref": "腳本或 Ansible 參照,必須能被安全路由與 reviewer 查到。",
- "schedule_or_monitoring_rule_ref": "排程、監控規則或 recurrence 偵測參照,避免同類告警只靠人工記憶。",
+ "schedule_or_monitoring_rule_ref": "排程、監控規則或 recurrence 偵測參照,避免同類告警只靠人工記憶或口頭交接。",
"km_update_plan": "KM 更新草稿與 負責人審查 計畫,避免錯知識直接固化。",
"automation_asset_record": "自動化資產紀錄,包含 asset id、owner、狀態、來源與下一步。"
},
@@ -10018,21 +10018,21 @@
"writebackTitle": "必須回寫的結果",
"writebacks": {
"incident_timeline_stage_update": "Incident timeline 必須標記目前階段、處置包、owner 與下一步。",
- "execution_or_manual_handoff_result": "無執行時也要寫入人工接手結果,不能只留下批准紀錄。",
+ "execution_or_manual_handoff_result": "無執行時也要寫入 AI 補齊或 break-glass 結果,不能只留下批准紀錄。",
"verifier_result": "Verifier 要能記錄成功、失敗、降級或尚未執行。",
"km_update_draft": "Hermes 產生 KM 草稿,負責人審查 後才可寫入高影響知識。",
"playbook_trust_update": "PlayBook 成功 / 失敗 / 未執行都要回寫 trust 與適用條件。",
"automation_asset_inventory_record": "資產清冊要留下 KM、PlayBook、腳本、排程、Verifier 的 ID 與狀態。"
},
"guardrailTitle": "阻擋原因與禁止誤讀",
- "blocker": "目前缺少可信修復候選;系統只能建立人工草案工作項,不能把 no-action、診斷結果或通用兜底當作已修復。",
+ "blocker": "目前缺少可信修復候選;系統必須建立 AI 補齊草案工作項,不能把 no-action、診斷結果或通用兜底當作已修復。",
"nextStep": "請先補 PlayBook 草案與 MCP evidence,再由 負責人審查 決定是否送審批;在此之前不會自動執行、不會寫入成功修復,也不會更新 KM 為已解決。",
"chainTitle": "真相鏈對照",
"chain": {
"stage": "目前階段",
"repair": "修復狀態",
"next": "真相鏈下一步",
- "human": "需要人工"
+ "human": "需要 AI 補齊"
},
"chainHint": "下方完整 status-chain 與 incident timeline 會用同一個 Incident 查詢;如果仍沒有資料,代表資料鏈路還沒把這筆告警完整串上。",
"openRuns": "打開 Runs",
@@ -10040,7 +10040,7 @@
},
"recurrence": {
"title": "重複告警工作項",
- "subtitle": "把 run_completed_no_repair、修復失敗與人工閘門接成可追蹤 work item",
+ "subtitle": "把 run_completed_no_repair、修復失敗與 AI 受控閘門接成可追蹤 work item",
"open": "待處理 {count}",
"automationGap": "無修復 {count}",
"failed": "修復失敗 {count}",
@@ -10110,7 +10110,7 @@
},
"handoffKinds": {
"ticket_proposal": "Ticket 提案",
- "manual_review": "人工覆核",
+ "manual_review": "AI 補齊覆核",
"unknown": "未知"
},
"handoffStatuses": {
@@ -10157,7 +10157,7 @@
"auto_repair_succeeded_unverified": "修復待驗證",
"auto_repair_failed": "修復失敗",
"auto_repair_recorded": "修復已記錄",
- "manual_gate": "需人工閘門",
+ "manual_gate": "需 AI 受控閘門",
"investigating": "調查中",
"run_completed_no_repair": "Run 完成無修復",
"source_correlation_review": "來源證據待配對",
@@ -10229,7 +10229,7 @@
"nextStatusChain": "等待狀態鏈批次回補,或打開 Incident 詳情確認",
"statusChainPending": "狀態鏈待回補",
"statuses": {
- "needsHuman": "需人工",
+ "needsHuman": "需 AI 補齊",
"failed": "執行失敗",
"verified": "已驗證",
"executed": "已執行",
@@ -10249,7 +10249,7 @@
"mcpCount": "MCP 調查 {count} 次",
"route": "MCP:{route}",
"emptyShort": "尚未連到 AI 證據",
- "manualGate": "下一步:人工審批",
+ "manualGate": "下一步:AI 受控審批",
"filters": {
"label": "AI 證據篩選",
"all": "所有 AI 證據",
@@ -10275,7 +10275,7 @@
"mcpObserved": "AI 已透過 MCP / 自建 MCP 收集證據,但尚未進入補救試跑或執行。",
"readOnlyDryRun": "AI 已走補救試跑,且最新紀錄沒有寫入 incident或auto-repair 狀態。",
"writeObserved": "最新補救紀錄含寫入旗標,審批前需確認狀態變更來源。",
- "blocked": "補救試跑未通過或被 gate 阻擋,需人工確認卡點。",
+ "blocked": "補救試跑未通過或被 gate 阻擋,需 AI 補齊確認卡點。",
"observed": "此列已連到補救歷史,請進入 執行時間線 查看完整證據。"
},
"summary": {
@@ -10283,8 +10283,8 @@
"mcpObservedDetail": "列表已連到 MCP / 自建 MCP 調查證據",
"readOnly": "只讀試跑",
"readOnlyDetail": "最新證據顯示 AI 已試跑且未寫狀態",
- "manualGate": "人工閘門",
- "manualGateDetail": "AI 已停在 批准 gate,需 approve / reject",
+ "manualGate": "AI 受控閘門",
+ "manualGateDetail": "AI 已停在 controlled gate,需 policy / verifier / approve 判定",
"writeObserved": "寫入旗標",
"writeObservedDetail": "需確認是否為預期自動修復結果",
"callbackObserved": "TG Callback",
@@ -10346,8 +10346,8 @@
"unlinked": "{count} 筆尚未連 Run",
"limit": "最近 {count} 筆視窗",
"verifiedRepair": "{count} 組已驗證修復",
- "sourceReview": "{count} 組 Sentry / SignOz 來源需人工配對",
- "manualGates": "{count} 組人工閘門"
+ "sourceReview": "{count} 組 Sentry / SignOz 來源需 AI 輔助配對",
+ "manualGates": "{count} 組 AI 受控閘門"
},
"states": {
"pending": "待執行",
@@ -10366,14 +10366,14 @@
"auto_repair_succeeded_unverified": "修復待驗證",
"auto_repair_failed": "修復失敗",
"auto_repair_recorded": "修復已記錄",
- "manual_gate": "需人工閘門",
+ "manual_gate": "需 AI 受控閘門",
"investigating": "調查中",
"run_completed_no_repair": "Run 完成無修復",
"source_correlation_review": "來源證據待配對",
"no_repair_record": "無修復記錄"
},
"workItemStatuses": {
- "owner_review_ready": "草案待 owner review",
+ "owner_review_ready": "草案待 controlled review",
"draft_ready": "草案已準備",
"open": "工作項待處理",
"blocked": "工作項阻塞",
@@ -10399,7 +10399,7 @@
"count": "{total} 筆;fallback {fallback};失敗 {failed}",
"emptyShort": "尚無詳情 / 歷史 callback",
"latest": "{action} · {incidentId}",
- "needsHuman": "Callback 失敗需人工確認",
+ "needsHuman": "Callback 失敗需 AI 補齊確認",
"captureLine": "Snapshot:{status};已捕捉 {captured} / 部分 {partial} / 未捕捉 {notCaptured}",
"captureMissing": "尚缺:{items}",
"captureStatuses": {
@@ -10429,7 +10429,7 @@
"sent": "Telegram callback reply 已用原格式送達。",
"fallbackSent": "Telegram HTML 回覆失敗後,已用純文字備援送達。",
"rescueSent": "Telegram 備援仍失敗後,已用救援純文字送達。",
- "failed": "Telegram callback reply 最終送達失敗,需人工確認。",
+ "failed": "Telegram callback reply 最終送達失敗,需 AI 補齊確認。",
"observed": "Telegram callback reply 已記錄,但狀態不屬於標準分類。"
},
"events": {
@@ -10544,13 +10544,13 @@
}
},
"kmCompletion": {
- "title": "KM Owner Review",
+ "title": "KM Controlled Review",
"status": "狀態:{status}",
"counts": "ready {ready} / blocked {blocked} / completed {completed} / failed {failed}",
"guardrail": "Guardrail:writes_on_read={writesOnRead};batch_writes_allowed={batchWrite};manual_review_required={manualReview}",
"related": "{entryId} · {readiness} · {nextAction}",
- "noRelated": "本 Incident 尚未對到 owner-review completion item。",
- "fetchFailed": "KM owner-review 摘要讀取失敗:{reason}",
+ "noRelated": "本 Incident 尚未對到 controlled-review completion item。",
+ "fetchFailed": "KM controlled-review 摘要讀取失敗:{reason}",
"openWorkItem": "開啟工作項",
"snapshotTitle": "Callback 當下 Evidence Snapshot",
"snapshotStatus": "當下狀態:{status};ready {ready} / blocked {blocked} / completed {completed} / failed {failed}",
@@ -10561,8 +10561,8 @@
"triageAutomation": "自動化:{state};可安全自動修復={safe}",
"triageBlocker": "卡點:{reason}",
"statuses": {
- "matched_owner_review": "已匹配 負責人審查",
- "no_related_owner_review": "未匹配 負責人審查",
+ "matched_owner_review": "已匹配受控審查",
+ "no_related_owner_review": "未匹配受控審查",
"fetch_failed": "讀取失敗",
"no_incident": "缺少 Incident",
"observed": "已記錄"
@@ -10628,7 +10628,7 @@
"primaryTitle": "目前由 {provider} 承接,AI lane 正常",
"primaryDetail": "後續備援順序:{standby}。Gemini只在 Ollama lanes都不可用後接手;目前下一步是持續監控與保留 fallback 證據。",
"fallbackTitle": "目前由 {provider} 接手,AI lane 已降級",
- "fallbackDetail": "已跳過:{skipped}。下一步:{action};需確認是否已有 Work Item、PlayBook與人工 gate。"
+ "fallbackDetail": "已跳過:{skipped}。下一步:{action};需確認是否已有 Work Item、PlayBook與 controlled gate。"
},
"degradedSummary": "目前由 {active} 接手;已跳過 {skipped};下一步:{action}",
"repairEvidence": {
@@ -10697,8 +10697,8 @@
"blockers": "卡點",
"writeFlags": "incident={incident} / autoRepair={autoRepair}",
"human": {
- "yes": "需人工",
- "no": "不需人工"
+ "yes": "需 AI 補齊",
+ "no": "不需 AI 補齊"
},
"fields": {
"stage": "階段",
@@ -10737,8 +10737,8 @@
"outcome": {
"summary": "處置結論",
"execution": "執行判定",
- "notification": "人工通知通道",
- "reason": "人工原因"
+ "notification": "受控通知通道",
+ "reason": "AI 補齊原因"
},
"applyGate": {
"title": "乾跑後套用閘門",
@@ -10785,9 +10785,9 @@
"releaseContractNextStepsTitle": "放行合約下一步",
"ownerReleaseDraftTitle": "AI 預填 Owner release 草案",
"ownerReleaseDraftAiPrefilled": "AI 已預填",
- "ownerReleaseDraftHumanDecision": "人工決策",
- "ownerReleaseDraftHumanOnly": "人工必審欄位",
- "ownerReleaseDraftStillHuman": "仍需人工批准",
+ "ownerReleaseDraftHumanDecision": "break-glass 決策",
+ "ownerReleaseDraftHumanOnly": "break-glass 必審欄位",
+ "ownerReleaseDraftStillHuman": "仍需 break-glass 批准",
"checklistTitle": "Owner 審查清單",
"forbiddenTitle": "禁止動作",
"gates": {
@@ -11016,7 +11016,7 @@
"sources": "來源範圍",
"sourcesStatus": "缺口 {blockers}",
"sourcesDetail": "原始碼範圍只顯示脫敏代號,未完成證據前不得切主來源。",
- "owner": "Owner gate",
+ "owner": "Owner evidence",
"ownerStatus": "待回覆 {waiting}",
"ownerDetail": "沒有負責人接受紀錄,就不把候選範圍當正式核准。",
"runtime": "Runtime gate",
@@ -11027,7 +11027,7 @@
"observability": "可觀測性",
"observabilityDetail": "主機、服務、網站入口、告警與接收證據。",
"knowledge": "知識與自動化",
- "knowledgeDetail": "KM、PlayBook、腳本、verifier 與 owner review。",
+ "knowledgeDetail": "KM、PlayBook、腳本、verifier 與 controlled review。",
"codeReview": "推版審查",
"codeReviewDetail": "產品級防木馬、Aider / ElephantAlpha 與 release gate。"
}
@@ -11400,8 +11400,8 @@
"actions": {
"repair_alert_intake_or_outbound_mirror": "修復告警入庫或出站鏡像",
"route_incident_to_mcp_gateway_and_evidence_collectors": "把事件導入 MCP Gateway 與證據收集器",
- "resolve_pending_or_expired_human_gate": "處理待處理 / 已過期人工閘門",
- "record_effective_execution_or_mark_manual_no_action": "記錄有效執行,或明確標成人工無動作",
+ "resolve_pending_or_expired_human_gate": "處理待處理 / 已過期 AI 受控閘門",
+ "record_effective_execution_or_mark_manual_no_action": "記錄有效執行,或明確標成 AI 補齊無動作",
"write_auto_repair_execution_or_blocker_reason": "寫入自動修復執行或阻塞原因",
"run_post_execution_verification": "執行事後驗證並保存結果",
"write_km_or_learning_evidence": "回寫 KM / learning evidence",
@@ -11430,7 +11430,7 @@
},
"runRefs": {
"mirrorRunState": "AwoooP 執行監控可以理解資安鏡像,但只能當只讀候選。",
- "readOnlyDryRun": "若未來產生試跑證據,也必須維持只讀與人工閘門語義。",
+ "readOnlyDryRun": "若未來產生試跑證據,也必須維持只讀與 AI 受控閘門語義。",
"ownerResponse": "負責人回覆已收到 / 已接受仍為 0,任何執行進一步行動都要等待人工收件。",
"activeGates": "主動執行期閘門仍為 0,不從執行監控頁開閘門或建立動作按鈕。"
}
@@ -11755,20 +11755,20 @@
"openTickets": "Tickets",
"empty": "無",
"flowTitle": "處理流程",
- "handoffTitle": "審批與人工接手",
+ "handoffTitle": "審批與 AI 受控接手",
"timelineEmpty": "尚未取得 Incident timeline。",
- "linkedExplanation": "此 Incident 已有 批准 / timeline 關聯;若下方待審清單為空,代表它可能已完成、過期、拒絕,或已轉成驗證後人工接手。",
+ "linkedExplanation": "此 Incident 已有 批准 / timeline 關聯;若下方待審清單為空,代表它可能已完成、過期、拒絕,或已轉成驗證後 AI 補齊接手。",
"unlinkedExplanation": "目前沒有對應 批准 id;這代表此 Incident不是等待批准的狀態,應從 Work Items / Runs 追下一步。",
"needsHuman": {
- "yes": "需要人工",
- "no": "不需人工"
+ "yes": "需要 AI 補齊",
+ "no": "不需 AI 補齊"
},
"metrics": {
"approvals": "關聯審批",
"stage": "目前階段",
"repair": "修復狀態",
"verification": "驗證",
- "handoff": "人工接手"
+ "handoff": "AI 受控接手"
},
"handoff": {
"approvalIds": "Approval IDs",
@@ -11792,9 +11792,9 @@
},
"nextAction": "下一步",
"blocker": "阻擋原因",
- "missingTitle": "缺少的 owner review / 安全路由欄位",
+ "missingTitle": "缺少的 control evidence / 安全路由欄位",
"missingEmpty": "未回報缺欄位;請仍以 runtime gate 與 verifier 為準",
- "openWorkItem": "開啟 owner review",
+ "openWorkItem": "開啟 controlled work item",
"openRuns": "追蹤 Runs"
},
"evidence": {
@@ -12086,13 +12086,13 @@
"action": {
"eyebrow": "下一步判斷",
"approval": {
- "title": "等待人工審批",
- "detail": "AI 已停在人工閘門,尚未恢復。請從審批頁核准或拒絕,所有決策都會回寫執行狀態與稽核紀錄。",
+ "title": "等待 AI 受控審批",
+ "detail": "AI 已停在 controlled gate,尚未恢復。請從審批頁核准、拒絕或排入 verifier / rollback,所有決策都會回寫執行狀態與稽核紀錄。",
"primary": "前往審批決策"
},
"manual": {
- "title": "需人工接手",
- "detail": "AI 無法安全閉環,或執行已失敗 / 超時。請回執行監控比對同專案任務,必要時交由 SRE 戰情室處置。",
+ "title": "需 AI 補齊接手",
+ "detail": "AI 尚未安全閉環,或執行已失敗 / 超時。請回執行監控比對同專案任務,排入 PlayBook、rollback、verifier 或 break-glass。",
"primary": "回執行監控"
},
"completed": {
@@ -12107,7 +12107,7 @@
},
"observe": {
"title": "觀察中",
- "detail": "目前尚未進入人工閘門或終止狀態。請沿時間線確認入站事件、工具呼叫與出站訊息是否有缺口。",
+ "detail": "目前尚未進入 AI 受控閘門或終止狀態。請沿時間線確認入站事件、工具呼叫與出站訊息是否有缺口。",
"primary": "回執行監控"
},
"evidence": {
@@ -12195,7 +12195,7 @@
"approvalDecision": {
"back": "返回審批佇列",
"viewTimeline": "查看執行時間線",
- "eyebrow": "人工審批閘門",
+ "eyebrow": "AI 受控審批閘門",
"title": "審批決策",
"timeout": "審批期限",
"empty": "--",
@@ -12210,7 +12210,7 @@
"reject": "執行已拒絕,正在回到時間線"
},
"notWaiting": {
- "title": "此執行目前不在人工審批狀態",
+ "title": "此執行目前不在 AI 受控審批狀態",
"detail": "目前狀態為 {state}。此頁不會顯示 approve / reject,請回執行時間線檢查最新狀態。"
},
"gate5Projection": {
@@ -12319,7 +12319,7 @@
"runId": "執行 ID:",
"approve": {
"title": "確認核准",
- "body": "核准後,執行會從人工閘門恢復,繼續交由 Runtime / MCP 閘道 執行。",
+ "body": "核准後,執行會從 AI 受控閘門恢復,繼續交由 Runtime / MCP 閘道 執行。",
"warning": "此決策會寫入執行狀態、批准 token與稽核軌跡。",
"confirm": "確認核准"
},
@@ -12480,13 +12480,13 @@
"action": {
"eyebrow": "下一步判斷",
"approval": {
- "title": "等待人工審批",
- "detail": "AI 已停在人工閘門,尚未 恢復執行。請從審批頁 approve或reject,所有決策都會回寫 執行狀態與audit。",
+ "title": "等待 AI 受控審批",
+ "detail": "AI 已停在 controlled gate,尚未恢復執行。請從審批頁 approve、reject 或排入 verifier / rollback,所有決策都會回寫執行狀態與 audit。",
"primary": "前往審批決策"
},
"manual": {
- "title": "需人工接手",
- "detail": "AI 無法安全閉環,或執行已失敗 / 超時。請回 Run 監控比對同專案任務,必要時交由 SRE 戰情室處置。",
+ "title": "需 AI 補齊接手",
+ "detail": "AI 尚未安全閉環,或執行已失敗 / 超時。請回 Run 監控比對同專案任務,排入 PlayBook、rollback、verifier 或 break-glass。",
"primary": "回 Run 監控"
},
"completed": {
@@ -12501,7 +12501,7 @@
},
"observe": {
"title": "觀察中",
- "detail": "目前尚未進入人工閘門或終止狀態。請沿時間線確認入站事件、工具呼叫與出站訊息是否有缺口。",
+ "detail": "目前尚未進入 AI 受控閘門或終止狀態。請沿時間線確認入站事件、工具呼叫與出站訊息是否有缺口。",
"primary": "回 Run 監控"
},
"evidence": {
@@ -12537,7 +12537,7 @@
"approvalDecision": {
"back": "返回審批佇列",
"viewTimeline": "查看 執行時間線",
- "eyebrow": "人工審批閘門",
+ "eyebrow": "AI 受控審批閘門",
"title": "審批決策",
"timeout": "審批期限",
"empty": "--",
@@ -12552,7 +12552,7 @@
"reject": "Run 已拒絕,正在回到 時間線"
},
"notWaiting": {
- "title": "此 Run 目前不在人工審批狀態",
+ "title": "此 Run 目前不在 AI 受控審批狀態",
"detail": "目前狀態為 {state}。此頁不會顯示 approve / reject,請回 執行時間線 檢查最新狀態。"
},
"remediation": {
@@ -12597,7 +12597,7 @@
"runId": "Run ID:",
"approve": {
"title": "確認核准",
- "body": "核准後,執行會從人工閘門 恢復執行,繼續交由 Runtime / MCP 閘道 執行。",
+ "body": "核准後,執行會從 AI 受控閘門恢復執行,繼續交由 Runtime / MCP 閘道 執行。",
"warning": "此決策會寫入 執行狀態、批准 token與稽核軌跡。",
"confirm": "確認核准"
},
@@ -14418,7 +14418,7 @@
"output": "更新 已收到 / 已接受 狀態,不執行"
},
"humanDecision": {
- "title": "等待人工決策",
+ "title": "等待 break-glass 授權決策",
"body": "資安閘門 需要 決策紀錄;AwoooP 批准、程式碼審查或進度數字都不能自動替代。",
"output": "人控決策,不是 執行期"
},
@@ -16504,7 +16504,7 @@
"sourceControlCutoverSeparated": {
"title": "主要來源切換分離",
"body": "GitHub 主要來源、Gitea 停用、分支 / 標籤參照或工作流程 / 機密設定都不能由準備佇列直接推進。",
- "prep": "只把主要來源相關缺口列入待人工決策清單。",
+ "prep": "只把主要來源相關缺口列入待 break-glass 授權清單。",
"guard": "不建立專案庫、不改可見性、不同步參照、不停用 Gitea。"
}
}
@@ -20573,13 +20573,13 @@
"accepted": "接受"
},
"domainStatus": {
- "owner_packet_required": "等待 owner packet 與脫敏 live evidence",
+ "owner_packet_required": "等待 owner evidence packet 與脫敏 live evidence",
"waiting_live_hash_and_owner_response": "等待 live hash、維護窗口與 owner response",
"waiting_receiver_route_and_receipt_evidence": "等待 receiver route、告警 receipt 與 reload owner",
"waiting_actor_before_after_and_recurrence_guard": "等待 actor、before / after 與防再發證據",
"manifest_mapped_read_only_runtime_gate_closed": "Manifest 已映射,runtime gate 仍關閉",
"waiting_manager_registry_readback": "等待 Wazuh manager registry 全量讀回",
- "draft_waiting_owner_review_runtime_gate_closed": "等待 owner review,runtime gate 仍關閉",
+ "draft_waiting_owner_review_runtime_gate_closed": "等待 owner evidence review,runtime gate 仍關閉",
"read_only_inventory_runtime_write_gate_closed": "只讀盤點完成,AI runtime write gate 仍關閉"
},
"domainBody": {
@@ -20837,7 +20837,7 @@
"wazuhManagerRegistryReviewerValidation": {
"eyebrow": "Wazuh manager registry reviewer validation",
"title": "Owner export 進來後,先由 reviewer 驗收脫敏清單",
- "subtitle": "這張卡固定 Wazuh manager registry owner export 的驗收規則:欄位、計數、公開別名矩陣、Dashboard API 修復讀回、唯讀 credential metadata、拒收內容與下一個 Gate 都先可視化;目前尚未收到、尚未接受,也不開 runtime。",
+ "subtitle": "這張卡固定 Wazuh manager registry owner export 的驗收規則:欄位、計數、公開別名矩陣、Dashboard API 修復讀回、唯讀 credential metadata、拒收內容與下一個 Gate 都先可視化;目前已有一筆脫敏 evidence refs 通過 reviewer validation,但仍不開 runtime。",
"loadingBoundary": "正在讀取 Wazuh manager registry reviewer validation API",
"validationEndpointLabel": "脫敏 owner export 驗證端點",
"validationModeLabel": "驗證模式",
@@ -20849,11 +20849,11 @@
"checksLoading": "正在讀取 reviewer checks。",
"checksFallback": "Reviewer checks 尚未由正式 API 讀回,維持 fallback 停止線。",
"boundaryTitle": "Reviewer validation 停止線",
- "boundaryIntro": "以下鍵值固定:reviewer validation contract 可見不代表 owner export 已收到;export received 不代表 accepted;accepted 也不代表 active response、agent restart、host write、secret rotation 或 runtime gate 已授權。",
+ "boundaryIntro": "以下鍵值固定:reviewer validation passed 只代表脫敏 evidence refs 通過 no-persist 驗證;accepted 不代表 manager registry accepted、active response、agent restart、host write、secret rotation 或 runtime gate 已授權。",
"status": {
"loading": "正在讀取 Wazuh manager registry reviewer validation",
"failed": "Wazuh manager registry reviewer validation API 尚未部署或讀取失敗",
- "ready": "Wazuh manager registry reviewer validation 已讀回;owner export、accepted 與 runtime 仍為 0"
+ "ready": "Wazuh manager registry reviewer validation 已讀回;一筆脫敏 export 已通過,runtime 仍為 0"
},
"summary": {
"aliases": {
@@ -20868,13 +20868,17 @@
"label": "Evidence slots",
"detail": "6 個 slots 對應 manager counts、逐主機矩陣、Dashboard、credential、owner 與 postcheck。"
},
+ "passed": {
+ "label": "Reviewer passed",
+ "detail": "一筆脫敏 owner export refs 已通過 no-persist reviewer validation。"
+ },
"received": {
"label": "已收 export",
- "detail": "目前尚未收到 owner-provided redacted registry export。"
+ "detail": "已收到一筆 owner-provided redacted registry export refs。"
},
"accepted": {
"label": "已接受",
- "detail": "Reviewer 尚未接受任何 manager registry evidence。"
+ "detail": "Reviewer 接受只讀 posture evidence,不代表主機納管完成。"
},
"runtime": {
"label": "執行期",
@@ -21179,7 +21183,7 @@
},
"p0Groups": {
"label": "P0 群組",
- "detail": "14 個 P0 群組需要 owner packet 與 reviewer check。"
+ "detail": "14 個 P0 群組需要 owner evidence packet 與 reviewer check。"
},
"evidenceRefs": {
"label": "證據參照",
@@ -21240,7 +21244,7 @@
},
"candidates": {
"label": "P0 候選",
- "detail": "14 個候選全部需要 owner packet 與 reviewer check。"
+ "detail": "14 個候選全部需要 owner evidence packet 與 reviewer check。"
},
"hosts": {
"label": "alias",
@@ -21344,7 +21348,7 @@
"gateLabel": "閘門",
"stateLabel": "狀態",
"boundaryTitle": "高價值配置收件邊界",
- "boundaryIntro": "以下鍵值固定:此卡只顯示 owner packet 草案與禁止動作,不代表 Nginx reload、workflow 修改、secret rotation、agent-bounty runtime 或任何主機操作已授權。",
+ "boundaryIntro": "以下鍵值固定:此卡只顯示 owner evidence packet 草案與禁止動作,不代表 Nginx reload、workflow 修改、secret rotation、agent-bounty runtime 或任何主機操作已授權。",
"summary": {
"packetCount": {
"label": "Packet 草案",
diff --git a/apps/web/src/app/[locale]/awooop/approvals/[run_id]/page.tsx b/apps/web/src/app/[locale]/awooop/approvals/[run_id]/page.tsx
index d689b7c7..8a9f275b 100644
--- a/apps/web/src/app/[locale]/awooop/approvals/[run_id]/page.tsx
+++ b/apps/web/src/app/[locale]/awooop/approvals/[run_id]/page.tsx
@@ -1,7 +1,7 @@
// =============================================================================
// WOOO AIOps - AwoooP Approval Decision
// =============================================================================
-// 人工審批必須回到 Run State / Timeline,避免 Approval 成為獨立孤島。
+// AI controlled approval must return to Run State / Timeline to avoid isolated Approval islands.
"use client";
diff --git a/apps/web/src/app/[locale]/awooop/runs/page.tsx b/apps/web/src/app/[locale]/awooop/runs/page.tsx
index cf9379a4..41f9ea4f 100644
--- a/apps/web/src/app/[locale]/awooop/runs/page.tsx
+++ b/apps/web/src/app/[locale]/awooop/runs/page.tsx
@@ -780,8 +780,8 @@ const LANE_CONFIG: Record<
className: "border-[#9bb6d9] bg-[#eef5ff] text-[#1f5b9b]",
},
approval: {
- label: "人工閘門",
- detail: "等待 SRE 批准或拒絕",
+ label: "AI 受控閘門",
+ detail: "等待 policy、check-mode 與 verifier 判定",
icon: ShieldCheck,
className: "border-[#d9b36f] bg-[#fff7e8] text-[#8a5a08]",
},
@@ -798,8 +798,8 @@ const LANE_CONFIG: Record<
className: "border-[#9bc7a4] bg-[#f0faf2] text-[#17602a]",
},
manual: {
- label: "人工升級",
- detail: "AI 無法閉環,需人工處置",
+ label: "AI 補齊升級",
+ detail: "補 PlayBook、rollback、verifier 或 break-glass 證據",
icon: TriangleAlert,
className: "border-[#e2a29b] bg-[#fff0ef] text-[#9f2f25]",
},
diff --git a/apps/web/src/app/[locale]/iwooos/page.tsx b/apps/web/src/app/[locale]/iwooos/page.tsx
index e37ac42a..a0929668 100644
--- a/apps/web/src/app/[locale]/iwooos/page.tsx
+++ b/apps/web/src/app/[locale]/iwooos/page.tsx
@@ -2482,9 +2482,9 @@ const wazuhManagerRegistryReviewerValidationBoundaries = [
'wazuh_manager_registry_reviewer_validation_outcome_lane_count=13',
'wazuh_manager_registry_reviewer_validation_evidence_slot_count=6',
'wazuh_manager_registry_reviewer_validation_forbidden_payload_count=27',
- 'wazuh_manager_registry_reviewer_validation_owner_registry_export_received_count=0',
- 'wazuh_manager_registry_reviewer_validation_owner_registry_export_accepted_count=0',
- 'wazuh_manager_registry_reviewer_validation_passed_count=0',
+ 'wazuh_manager_registry_reviewer_validation_owner_registry_export_received_count=1',
+ 'wazuh_manager_registry_reviewer_validation_owner_registry_export_accepted_count=1',
+ 'wazuh_manager_registry_reviewer_validation_passed_count=1',
'wazuh_manager_registry_reviewer_validation_quarantined_count=0',
'wazuh_manager_registry_reviewer_validation_manager_registry_accepted_count=0',
'wazuh_manager_registry_reviewer_validation_post_enable_readback_passed_count=0',
@@ -9817,22 +9817,22 @@ function IwoooSWazuhManagerRegistryReviewerValidationBoard() {
tone: 'steady',
},
{
- key: 'slots',
- value: summary ? String(summary.evidence_slot_count) : loading ? '...' : '6',
+ key: 'passed',
+ value: summary ? String(summary.reviewer_validation_passed_count) : loading ? '...' : '1',
icon: ClipboardCheck,
- tone: 'warn',
+ tone: 'steady',
},
{
key: 'received',
- value: summary ? String(summary.owner_registry_export_received_count) : loading ? '...' : '0',
+ value: summary ? String(summary.owner_registry_export_received_count) : loading ? '...' : '1',
icon: FileWarning,
- tone: 'locked',
+ tone: summary?.owner_registry_export_received_count ? 'steady' : 'locked',
},
{
key: 'accepted',
- value: summary ? String(summary.owner_registry_export_accepted_count) : loading ? '...' : '0',
+ value: summary ? String(summary.owner_registry_export_accepted_count) : loading ? '...' : '1',
icon: Lock,
- tone: 'locked',
+ tone: summary?.owner_registry_export_accepted_count ? 'steady' : 'locked',
},
{
key: 'runtime',
@@ -9925,8 +9925,8 @@ function IwoooSWazuhManagerRegistryReviewerValidationBoard() {
{slot.slot_id}