|
| 1 | +#!/usr/bin/env python3 |
| 2 | +"""Anti-AI style/static quality guard for Fractovision. |
| 3 | +
|
| 4 | +Focus: artifact naming/style risk, overly synthetic language markers, |
| 5 | +and aggressive visual/branding defaults that often indicate template-heavy slop. |
| 6 | +""" |
| 7 | +from __future__ import annotations |
| 8 | + |
| 9 | +import re |
| 10 | +from pathlib import Path |
| 11 | +from typing import Any, Dict |
| 12 | + |
| 13 | +ROOT = Path(__file__).resolve().parents[1] |
| 14 | + |
| 15 | +RULES = [ |
| 16 | + { |
| 17 | + "name": "文本 emoji 过密(可能偏机器默认语体)", |
| 18 | + "pattern": re.compile(r"[\U0001F300-\U0001FAFF\u2600-\u27BF]"), |
| 19 | + "limit": 30, |
| 20 | + }, |
| 21 | + { |
| 22 | + "name": "过多动效/幻觉模板符号(CSS/JS 滥用迹象)", |
| 23 | + "pattern": re.compile(r"linear-gradient\(|radial-gradient\(|box-shadow|filter:\s*blur\(|backdrop-filter", re.IGNORECASE), |
| 24 | + "limit": 40, |
| 25 | + }, |
| 26 | + { |
| 27 | + "name": "过量全大写词(口号化倾向)", |
| 28 | + "pattern": re.compile(r"\b[A-Z]{5,}\b"), |
| 29 | + "limit": 26, |
| 30 | + }, |
| 31 | +] |
| 32 | + |
| 33 | +TARGET_EXTENSIONS = {".md", ".txt", ".py", ".json", ".yml", ".yaml", ".js", ".ts", ".tsx", ".css", ".html", ".mdx"} |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | +def collect_style_guard_report(root: Path | None = None) -> Dict[str, Any]: |
| 38 | + root = root or ROOT |
| 39 | + checks = [] |
| 40 | + |
| 41 | + for rule in RULES: |
| 42 | + total = 0 |
| 43 | + samples = [] |
| 44 | + for p in root.rglob('*'): |
| 45 | + if not p.is_file() or '.git' in p.parts or p.name == 'anti_ai_style_guard.py': |
| 46 | + continue |
| 47 | + if p.suffix.lower() not in TARGET_EXTENSIONS: |
| 48 | + continue |
| 49 | + try: |
| 50 | + text = p.read_text(encoding='utf-8', errors='ignore') |
| 51 | + except Exception: |
| 52 | + continue |
| 53 | + hits = rule['pattern'].findall(text) |
| 54 | + if hits: |
| 55 | + total += len(hits) |
| 56 | + if len(samples) < 2: |
| 57 | + samples.append(str(p.relative_to(root))) |
| 58 | + |
| 59 | + checks.append( |
| 60 | + { |
| 61 | + "name": rule['name'], |
| 62 | + "ok": total <= rule['limit'], |
| 63 | + "count": total, |
| 64 | + "limit": rule['limit'], |
| 65 | + "sample_files": samples, |
| 66 | + "fix": "降低模板化视觉指纹,结合 kill-ai-slop 风格清洗策略重新组织配色与动效节奏", |
| 67 | + } |
| 68 | + ) |
| 69 | + |
| 70 | + anti_doc = root / 'references' / 'content-guidelines.md' |
| 71 | + checks.append( |
| 72 | + { |
| 73 | + "name": "反AI风格执行文档", |
| 74 | + "ok": anti_doc.exists(), |
| 75 | + "fix": "补齐反AI风格文档(content-guidelines)并绑定 doctor 闭环", |
| 76 | + "sample_files": [str(anti_doc.relative_to(root))] if anti_doc.exists() else [], |
| 77 | + } |
| 78 | + ) |
| 79 | + |
| 80 | + return { |
| 81 | + "checks": checks, |
| 82 | + "passed": all(c['ok'] for c in checks), |
| 83 | + } |
0 commit comments