test(awooop): guard controlled automation copy
Some checks failed
Code Review / ai-code-review (push) Has been cancelled
CD Pipeline / tests (push) Successful in 5m14s
CD Pipeline / build-and-deploy (push) Failing after 1m48s
CD Pipeline / post-deploy-checks (push) Has been skipped

This commit is contained in:
Your Name
2026-06-27 22:38:28 +08:00
parent 62309d3990
commit 219fc3835c
3 changed files with 121 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
from __future__ import annotations
import runpy
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
def test_awooop_controlled_automation_copy_guard_blocks_legacy_manual_gate_text() -> None:
guard = runpy.run_path(
str(ROOT / "scripts" / "security" / "awooop-controlled-automation-copy-guard.py")
)
guard["validate"](ROOT)

View File

@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""Guard AwoooP public copy against legacy manual-gate defaults.
This guard is static and read-only. It prevents AwoooP pages and serialized
message payloads from reintroducing old manual-gate wording as the default
state for low / medium / high controlled automation.
"""
from __future__ import annotations
import argparse
from pathlib import Path
TEXT_FILES = [
Path("apps/web/messages/zh-TW.json"),
Path("apps/web/messages/en.json"),
]
AWOOOP_SOURCE_ROOT = Path("apps/web/src/app/[locale]/awooop")
ALERTS_ROUTE = AWOOOP_SOURCE_ROOT / "alerts" / "page.tsx"
FORBIDDEN_FRAGMENTS = [
"待人工決策",
"等待人工決策",
"阻塞與人工閘門",
"人工接手",
"人工決策佇列",
"人工關卡",
"人工 gate",
"人工閘門",
"人工升級",
"owner review",
"owner packet",
"manual gate",
"manual handoff",
]
REQUIRED_FRAGMENTS = [
"待 AI 受控決策",
"阻塞與 AI 受控隊列",
"AI 處置包與工作項",
"受控執行邊界",
"受控授權閘門",
"controlled gate",
"controlled review",
]
def _iter_guarded_files(root: Path) -> list[Path]:
files = [root / path for path in TEXT_FILES]
source_root = root / AWOOOP_SOURCE_ROOT
files.extend(sorted(source_root.rglob("*.tsx")))
return files
def validate(root: Path) -> None:
root = root.resolve()
violations: list[str] = []
guarded_text = []
for path in _iter_guarded_files(root):
if not path.exists():
violations.append(f"{path.relative_to(root)}: missing guarded file")
continue
text = path.read_text(encoding="utf-8")
guarded_text.append(text)
for line_number, line in enumerate(text.splitlines(), start=1):
for fragment in FORBIDDEN_FRAGMENTS:
if fragment in line:
relative = path.relative_to(root)
violations.append(f"{relative}:{line_number}: forbidden {fragment!r}")
alerts_route = root / ALERTS_ROUTE
if not alerts_route.exists():
violations.append(f"{ALERTS_ROUTE}: missing AwoooP Alerts route")
else:
route_text = alerts_route.read_text(encoding="utf-8")
if "#ai-alert-card-delivery-readback" not in route_text:
violations.append(f"{ALERTS_ROUTE}: missing ai-alert-card-delivery-readback redirect target")
combined_text = "\n".join(guarded_text)
for fragment in REQUIRED_FRAGMENTS:
if fragment not in combined_text:
violations.append(f"messages/source: missing required controlled automation text {fragment!r}")
if violations:
formatted = "\n".join(violations[:40])
raise SystemExit(f"BLOCKED awooop_controlled_automation_copy_guard:\n{formatted}")
def main() -> int:
parser = argparse.ArgumentParser(description="Validate AwoooP controlled automation public copy.")
parser.add_argument("--root", default=".")
args = parser.parse_args()
validate(Path(args.root))
print("AWOOOP_CONTROLLED_AUTOMATION_COPY_GUARD_OK")
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -91,6 +91,10 @@ def validate(root: Path) -> None:
str(root / "scripts" / "security" / "iwooos-frontend-display-redaction-guard.py")
)
iwooos_frontend_display_redaction_guard["validate"](root)
awooop_controlled_automation_copy_guard = runpy.run_path(
str(root / "scripts" / "security" / "awooop-controlled-automation-copy-guard.py")
)
awooop_controlled_automation_copy_guard["validate"](root)
wazuh_readonly_route_boundary_guard = runpy.run_path(
str(root / "scripts" / "security" / "wazuh-readonly-route-boundary-guard.py")
)