发布审查闸门(Publish Review Gate)
何时用
- 用户发现公开仓库里的文档带"🟢 可发布"之类自我宣称,但没有任何外部审查记录
- 用户说"从根本解决"、"防止没审就发出去"
- 任何"文档/资产会自动流向公开通道"的场景
🔴 先认清根因
问题通常不在"审得不够",而在「"可发布"这个标记可以由文档自己写」。
要验证,去线上抓一份原文看头部——常能看到:
状态:🟢 可发布(引用已联网复核)
而实际另有独立复核判定它为 打回。
链路是:作者写 → 文档自标可发布 → 推公开仓库 → 平台上没有任何外部审查信号。 读者与 AI 爬虫无法分辨"审过且放行"与"自己说行"。
⚠️ 放大效应:若仓库目的之一是被 AI 检索引用(GEO),那"被引用了错误内容"比不被引用更糟——它成为错误在 AI 答问中的传播源。
四步搭建
1. 先摸清暴露面(别凭印象)
- 列出仓库所有远端:
git remote -v(常有 GitHub/Gitee/AtomGit 多镜像) - 文件是否已公开:
git ls-files <dir>+git merge-base --is-ancestor <文件末次提交> origin/main→ 是origin/main的祖先 = 已推送公开 - 注意:工作区可能有未提交修改,公开的是已提交版本,判断时要比对已提交内容
- 有 GitHub 连接器时可直接抓线上原文复核(
get_file_contents)
2. 定义机器可校验的审查标记
要求每份发布物头部带 HTML 注释块(HTML 注释在渲染时不可见,不污染阅读):
<!-- REVIEW-GATE
review-status: in-review # unverified | in-review | verified | contested
reviewed-by: <独立席位名>
review-date: 2026-09-15
review-ref: <审查意见文件路径>
verdict: rejected # pass | conditional | rejected
-->
规则要点:
- G-1 无标记不得发布
- G-2 自称无效:正文出现"可发布"自夸但
review-status != verified→ 失败 - G-3 结论不得矛盾:
rejected却verified→ 失败 - G-4 独立席位:审查者须与作者不同线(工具只能提示人工核)
- G-5 时效复核:审查日期 > 180 天 → 警告
- G-6 争议件须显式标红:
conditional/rejected时正文必须有⚠️ 待修订区块
3. 🔑 关键设计:基线豁免(否则会锁死仓库)
存量问题往往几十份全红。直接上闸门 = 用户再也推不上去。
- 建
baseline.txt登记已存在且已公开的历史问题 → 只警告、不阻断 - 退出码只反映"新增问题"
- 校验器要能提示"哪些基线条目已失效、可从清单移除"
- 清单只减不增:往里加新文件名 = 掩盖新问题
4. 装本地强制闸门(不需要任何凭据)
为什么优先做这个:CI 只报警,pre-push 钩子直接拦;且完全不依赖平台权限。
装在 <repo>/.git/hooks/pre-push(不在版本控制内,不影响仓库内容,删掉即卸载)。
🔴 钩子必须零外部命令依赖。 两次真实翻车:
- v1:用
git rev-parse --show-toplevel定位仓库根 → git 不在 PATH 时静默放过(最危险的失败模式:看起来装了,其实没拦)- v2:改纯 shell 参数展开,但
$0是相对路径.git/hooks/pre-push时,${GIT_DIR%/*}无法再剥离 → 退化成.git→ 报"无 docs 目录"后放行- v3 正确做法:纯参数展开 + 回退保护
不用SELF="$0"; HOOK_DIR="${SELF%/*}"; GIT_DIR="${HOOK_DIR%/*}"; REPO_ROOT="${GIT_DIR%/*}" [ "$REPO_ROOT" = "$GIT_DIR" ] && REPO_ROOT="." # ← 相对路径回退,关键git/dirname/basename。
依赖缺失时必须"显式告知并放行"(避免钩子本身把工作卡死),但必须 echo 出来——静默放行是隐患。
留逃生口:git push --no-verify。
5. 服务端闸门(需凭据,通常要用户配合)
CI 工作流 + 分支保护才是真闭环:
.github/workflows/*.yml跑校验器- 分支保护:禁止直推 main、要求 PR、要求 CI 通过
先探清能不能自己做:
gh --version && gh auth status # token 常已失效
- 若 MCP 连接器只提供 PR/文件/issue 类工具(通常没有分支保护接口)→ 服务端这步必须用户执行一条命令:
gh auth login -h github.com -p https -s repo,workflow -w - 绝不代为接触 token;恢复后自己用
gh api做,且执行前把完整命令给用户过目
诚实声明(必须写进交付物)
这套闸门覆盖不到:
- 服务端:本地钩子只在本机拦,换机器或网页直接编辑都能绕过
- 镜像远端:Gitee/AtomGit 等镜像未覆盖
- 判定深度:只查"有没有标记",不判断审查质量;标记可被伪造
- 存量:基线只是"登记不阻断",并未修复
配套:修订令(不删文件)
对已公开且已发现缺陷的文档,不删除、不改写历史结论,只在头部加:
> ⚠️ **修订说明(日期)**:本件存在以下已确认问题,正在修订,暂缓对外引用。
> 1. ……
理由:删除会造成引用断链(外部引用、DOI、AI 已抓取的语料)。
落地顺序建议
- 摸暴露面(只读)→ 2. 定标记规则 → 3. 建基线 → 4. 装钩子 + 实测拦截能力(必须真的造一个不合格样本验证 exit 1)→ 5. 用户恢复凭据 → 6. 服务端分支保护
Scan to join WeChat group