发布前合规流水线最小边界与执行约定

目标

用于降低发布风险,提供可复核、可审计的“文本覆盖 / 状态报告”流程。目标是 risk grading + human review,不是绕过平台或当地审查。

明确不做的事

  • 不提供、不升级、不封装“变形 / 拆字 / alias”等用于 evading 关键词风控的机制。
  • 不把“零命中”当作 legality proof。
  • 不做自动 publish approved 裁决。
  • 不读取、聚合、回显受限制原件的全文、摘要、摘录,包括但不限于 ${DATA_ROOT}/敏感词.md 与用户指定的受限碎碎念原件。
  • 不把 sensitive-guard scan 的命中原词打印到对话、日志、导出或模型上下文。

适用范围

  • 自己或已授权文本的发布前检查。
  • 平台 TOS / 目标辖区要求下的事实性、中性表述复核。
  • NSFW 可见性、私密库名、凭据/个人资料、敏感词 categories 的分层检查。

铁律

  1. 分层独立检查:privacy-redaction、nsfw-output-guard、sensitive-words-guard、custom rules 分开执行,不能互相替代。
  2. 一切 uncertain 场景 fail-closed:进入人工复核队列,而不是放行。
  3. Restricted originals 仅可登记边界、hash、时间:不能 ingest 或摘要。
  4. 报告最低必要信息:命中数量、 touched files、规则编号/ category、位置范围、输入/清单 hash;不显示原词。
  5. Media separate:文本词表不能代替图像/视频/音频/二进制人工检查。

管道

  1. 授权与 privacy 层

    • 确认文本可进入 agent 流程。
    • 跑 privacy-redaction,移除真正凭证、Cookie/JWT/Authorization、身份资料。
    • 对 Authorization/Cookie/JWT 等仍应完整删除/替换,不能只保留首尾片段。
  2. 标准化层

    • NFKC、全半角、标点/空白归一化。
    • 保留 orig_offsets ↔ normalized_offsets 映射。
    • 记录 input_sha256、normalized_sha256、使用的 normalizer_version。
  3. 本地检测层

    • 以 GNU grep / Aho-Corasick / Trie 在本地执行。
    • 拒绝 symbolic link、device/special files、二进制、非 UTF-8、扫描错误。
    • 仅统计不回显:
      • tier1_political 命中数
      • tier2_porn_ad 命中数
      • custom 命中数
      • context_rules 命中数
    • 如果清单缺失、语法错误、目录不可读:ERROR 且不放行。
  4. 风格与版块层(版本化)

    • NSFW 文本/names:按 ${KNOWLEDGE_ROOT}/meta/nsfw-filter.txt pattern 清单做 grep。
    • 路径与名称均用同表检查;不得只隐藏前端卡片。
    • 媒体需单独授权人工检查。
  5. 分级层

    • Allow:无命中、无 high-risk context、无媒体未审。
    • Review:任何命中或 context/引用风险、需要人工裁决。
    • Block:明确 prohibited claim、批量风险、检测失败、缺 reviewer、媒体未审。
    • 无 status 的结果不算 pass
  6. 人工复核层

    • 复核 UI 只显示命中窗口 hash / rule type / offsets。
    • 审核人记录 approve / revise / reject 与 reason。
    • 误报应记录 scoped exception,而不是关闭整个 ruleset。
    • high-risk topic 需要 second approval。
  7. 发布与审计层

    • 发布记录:input hash、normalized hash、wordlist hashes、platform/jurisdiction、reviewer、decision、timestamp。
    • 有被拒/失败文本,不追加为“已通过”证据。
    • 清理所有临时 patterns、扫描输出、映射与 hits files。

本地检测模式参考

采用 nsfw-output-guard 已记录的 shell 模式:

  • umask 077
  • tmp dir 700/600
  • 先验证文件、清单、UTF-8
  • grep 仅在本地 subprocess 中运行
  • stdout 只输出 ..._NO_LIST_HITS / ..._LIST_HITS / ..._ERROR
  • exit code:0 无命中,1 命中,2 未完成检查
  • no scan error allowed

关于 sensitive-guard 的边界

sensitive_guard.Guard 可用于只读检测:

  • Guard(tiers=("tier1", "custom"), wordlist_dir=...) 仅作 detection backend。
  • glossary 不按 category 自动隔离;不能只改 tiers 声称三类已拆开。
  • mask() / dots / alias 不是隐私脱敏,也不保证远端 provider 接受,不能用于 bypass。
  • 不向远端模型发送词表或探测词。

处理受限原件

  • ${DATA_ROOT}/敏感词.md
  • ${DATA_ROOT}/ku/yunlu/99 - 随手记/已合并碎碎念原件/已合并碎碎念原件-001.md
  • 旧 /tmp classify/cands dump

以上仅做边界记录、大小、时间、sha256 证据;不得进入模型上下文或 API。名字拼写、分类、映射报告留在本地。

报告 Schema(最小)

{
  "target": "authorized-copy",
  "input_sha256": "...",
  "normalized_sha256": "...",
  "wordlists": [
    {"tier": "tier1_political", "sha256": "...", "hits": 0},
    {"tier": "custom", "sha256": "...", "hits": 0}
  ],
  "files_scanned": 0,
  "files_with_hits": 0,
  "context_rule_hits": 0,
  "nsfw_status": "no_list_hits",
  "privacy_status": "redacted",
  "decision": "allow|review|block",
  "reviewers": [],
  "reason": "human-readable, policy-code or category only; no hit word"
}

命中的词语本身 不进入 报告、日志和 Git。

局限

  • 这是内容覆盖检查,不对 legality、事实准确性、争议性做 definitive ruling。
  • 不能把 wordlist 匹配 mistaken 为 legal advice。
  • 无法识别语义规避、未登记变体、非文本或 Codex/OpenCode 生成后的人工化改写。
  • 最终 publish decision 仍需视为 human/compliance decision。

关联

  • ${KNOWLEDGE_ROOT}/skills/nsfw-output-guard/SKILL.md
  • ${KNOWLEDGE_ROOT}/skills/sensitive-words-guard/SKILL.md
  • ${HOME}/.hermes/shared/sensitive-guard/sensitive_guard.py
  • ${KNOWLEDGE_ROOT}/ops/agent-content-rules-20261010.md
  • ${KNOWLEDGE_ROOT}/meta/knowledge-ingestion-policy.md