fix(governance): redact legacy agent evidence display terms
All checks were successful
Code Review / ai-code-review (push) Successful in 13s
CD Pipeline / tests (push) Successful in 1m27s
CD Pipeline / build-and-deploy (push) Successful in 5m18s
CD Pipeline / post-deploy-checks (push) Successful in 18s

This commit is contained in:
Your Name
2026-06-13 04:46:14 +08:00
parent 047b6d2ea2
commit 1b5eb3c328
6 changed files with 153 additions and 29 deletions

View File

@@ -43,6 +43,7 @@ def load_latest_ai_agent_candidate_operation_dry_run_evidence(
_require_gate_requirements(payload, str(latest))
_require_operator_handoffs(payload, str(latest))
_require_redaction_contract(payload, str(latest))
_require_no_forbidden_display_terms(payload, str(latest))
_require_rollup_consistency(payload, str(latest))
return payload
@@ -250,6 +251,56 @@ def _require_redaction_contract(payload: dict[str, Any], label: str) -> None:
raise ValueError(f"{label}: display redaction fields must remain false: {unsafe}")
def _require_no_forbidden_display_terms(payload: dict[str, Any], label: str) -> None:
forbidden_terms = {
"工作視窗",
"對話內容",
"批准!繼續",
"In app browser",
"My request for Codex",
"browser_context",
"codex_user_message",
"prompt_text",
"raw payload",
"raw_prompt",
"private reasoning",
"private_reasoning",
"chain_of_thought",
"bot_token",
"authorization header",
"authorization_header",
"secret value",
"secret_value",
"raw tool output",
"raw_tool_output",
"raw Telegram payload",
"raw_telegram_payload",
"work window transcript",
"work_window_transcript",
"internal collaboration transcript",
}
hits: list[str] = []
def walk(value: Any, path: str) -> None:
if isinstance(value, dict):
for key, nested in value.items():
walk(nested, f"{path}.{key}" if path else str(key))
return
if isinstance(value, list):
for index, nested in enumerate(value):
walk(nested, f"{path}[{index}]")
return
if isinstance(value, str):
matched = sorted(term for term in forbidden_terms if term in value)
if matched:
hits.append(f"{path}: {', '.join(matched)}")
walk(payload, "")
if hits:
raise ValueError(f"{label}: forbidden display terms found: {hits}")
def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None:
rollups = payload.get("rollups") or {}
truth = payload.get("dry_run_truth") or {}

View File

@@ -40,6 +40,7 @@ def load_latest_ai_agent_runtime_verifier_evidence_review(
_require_schema(payload, str(latest))
_require_runtime_boundaries(payload, str(latest))
_require_review_contract(payload, str(latest))
_require_no_forbidden_display_terms(payload, str(latest))
_require_rollup_consistency(payload, str(latest))
return payload
@@ -115,6 +116,58 @@ def _require_review_contract(payload: dict[str, Any], label: str) -> None:
raise ValueError(f"{label}: {flag} must remain false")
def _require_no_forbidden_display_terms(payload: dict[str, Any], label: str) -> None:
forbidden_terms = {
"工作視窗",
"對話內容",
"批准!繼續",
"In app browser",
"My request for Codex",
"browser_context",
"codex_user_message",
"prompt_text",
"raw payload",
"raw_prompt",
"private reasoning",
"private_reasoning",
"chain_of_thought",
"bot_token",
"authorization header",
"authorization_header",
"secret value",
"secret_value",
"raw tool output",
"raw_tool_output",
"raw Telegram payload",
"raw_telegram_payload",
"unredacted canonical payload",
"unredacted_canonical_payload",
"work window transcript",
"work_window_transcript",
"internal collaboration transcript",
}
hits: list[str] = []
def walk(value: Any, path: str) -> None:
if isinstance(value, dict):
for key, nested in value.items():
walk(nested, f"{path}.{key}" if path else str(key))
return
if isinstance(value, list):
for index, nested in enumerate(value):
walk(nested, f"{path}[{index}]")
return
if isinstance(value, str):
matched = sorted(term for term in forbidden_terms if term in value)
if matched:
hits.append(f"{path}: {', '.join(matched)}")
walk(payload, "")
if hits:
raise ValueError(f"{label}: forbidden display terms found: {hits}")
def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None:
rollups = payload.get("rollups") or {}
checks = payload.get("evidence_checks") or []