提出在AI生成diff合并前必须有名为「签署人」的人类接受爆炸半径,解决免费AI会话无审计追踪的根本问题。
周一的早上,你打开共享代码库,发现已经有三个 Pull Request 合并进了 main。提交信息里写着"agent 循环"、"免费主机",以及一个在周五晚上跑得太久的实验。团队里没人能复现那些会话,因为那个共享的免费服务器已经不再保存聊天记录了。现在,你成了那个必须决定这些 diff 是保留、回滚还是等待签名者的人。
共享的免费层级编码循环会以一种枯燥的方式失败——表面上看起来像是效率高,直到缺少 review。模型会起草一个 patch,主机会保持进程存活,git 依然会记录一次合并。但 git 不会记录一个在聊天历史消失之后读过爆炸半径的人。这份 playbook 给你一个签名者窗口、三个具名席位,以及一个可以粘贴的一页 Wiki SOP。
一个 AI 生成的 patch 在具名人类在 git 中接受爆炸半径之前,不是完整的变更。工具痕迹在免费会话结束时就会消失,所以 agent 不是负责人,也不是审计追踪。你需要一个签名者——一个在聊天历史永远消失之后仍然能解释这个 diff 的人。而且你需要在 token 开始流转之前就写好这个名字,而不是等到 main 已经变红之后。
等到周一早上会训练团队把沉默当作对未签名合并的同意。下面的 SOP 把缺少签名者视为一次失败的关卡,就像缺少测试会让构建失败一样。社会性记忆不会撑过一个长周末,这就是为什么 Wiki 页面必须枯燥且简短。如果你找不到一个 handle,你就不是一个 review;你只是有一个希望。
在任何人在共享编码循环中启动之前,在一个 Wiki 页面上填好三个席位。隔夜所有权、拓扑猜测和 staging 关卡放在其他页面上,让这个 run 专注于 diff。循环启动者是职责,不是第四个王座,而且这个职责可以在每次 spike 时轮换。
Diff signer —— 读取 patch 并在 PR 上写 SIGNER: @handle 的人类。
Merge captain —— 在签名者行存在且窗口仍然开放时,允许按下合并的人。
Rollback owner —— 如果 CI 或生产环境出问题,在约定窗口内执行回滚的人。
启动循环的人和 diff signer 必须是不同的人——只要有两个可用的人类。如果你是一个人,你仍然要把自己的名字写在签名者席位上,然后在合并授权、计费或删除路径之前等待一个睡眠周期。那个暂停就是控制点;跳过它,这个 SOP 就只是做秀。在第一个工具调用之前命名 rollback owner,因为在 main 坏掉之后再找志愿者不是一次交接。
把下面的块复制到你的团队 Wiki 中。在循环之前替换括号里的字段,而不是回滚之后。保持页面足够短,能在手机上两分钟读完。
# Diff-Signer SOP (AI-authored patches)
Status: ACTIVE
Lab date (UTC): YYYY-MM-DD
Shared host: [workstation or free server label]
Model access: [free-tier label only; no guessed quotas]
Repository: [org/repo]
Branch: [topic branch]
Loop starter (duty): [@handle]
Diff signer: [@handle]
Merge captain: [@handle]
Rollback owner: [@handle]
Signer window: [start UTC] → [end UTC]
Path allowlist: [src/app/ docs/]
Out of scope: [secrets, lockfiles, prod Terraform]
Rollback window: [example: 4 hours after merge]
## Gate
- No merge to main without `SIGNER: @handle` in the PR body.
- No merge if the signer window has expired.
- No merge if the rollback owner is offline and the diff touches infra.
## After the loop
- PR URL:
- Commit SHA:
- Signer read the diff without the chat transcript: [yes/no]
如果页面超过一屏,你就混入了 runbook。把主机健康、prompt 拓扑和隔夜覆盖拆分到签名者页面之外。一个试图管理所有 AI 恐惧的 Wiki 在周五不会被填上。空字段意味着循环不会启动。
按顺序遵循这些步骤。在第四步在 Wiki 页面上变绿之前不要启动 agent。
这是一个你可以粘贴的小命令序列。把它当作提案,直到你在自己的克隆仓库里跑过它。
# Proposal: create the review branch before the agent writes anything
git fetch origin
git switch -c lab/ai-patch-$(date -u +%Y%m%d) origin/main
git push -u origin HEAD
# Proposal: open a PR with a signer placeholder the local check can read
gh pr create --title "lab: AI patch pending signer" --body "$(cat <<'EOF'
SIGNER: UNASSIGNED
ROLLBACK: @handle
ALLOWLIST: src/app/ docs/
WIKI: https://wiki.example/diff-signer-sop
EOF
)"
如果你的团队不用 gh,在浏览器里创建同样的 PR,并把 SIGNER: 作为 body 的第一行。重点是 body 里的 token,而不是 CLI 的口味。带有真实 PR 的空分支胜过一个笔记本上未 review 的文件堆。
你不是在 review 模型的人格。你是在 review 一个必须在免费会话消失之后存活下来的 git diff。先读文件树,只有在树已经可辩护的情况下才读聊天记录。
先打开 PR 但不要先打开聊天记录,这样你评判的是文件,而不是 agent 讲的故事。
如果 patch 触碰了 allowlist 之外的路径,拒绝它——即使改动看起来很聪明,或者提交信息听起来很自信。
如果你不能用一句话在 Wiki 页面上 SHA 旁边解释失败模式,拒绝这个 patch。
如果你接受,用 SIGNER: @yourhandle 和一个 UTC 时间戳替换 SIGNER: UNASSIGNED。
告诉 merge captain 窗口仍然开放,如果你也是启动循环的人且存在第二个人类,不要合并。
一个有用的本地检查像下面的命令。针对远程 topic 分支运行,而不是 agent 仍然拥有的工作树。
git fetch origin
git diff origin/main...origin/lab/ai-patch-20260911 --stat
git diff origin/main...origin/lab/ai-patch-20260911
先读 stat 输出再读完整 diff,这样改动的规模是可见的。如果移动了大量文件,你可能没有签名者窗口;你有一个重写。重写需要不同的 playbook、更长的窗口和一个醒着的 merge captain。
下面的产物是一个小的 Python 关卡。它从文件读取 PR body,并在缺少真实签名者行时失败。保存为 tools/check_signer.py,在任何人在合并按钮上之前在你的笔记本上运行它。
#!/usr/bin/env python3
"""Fail if an AI-authored PR body has no human SIGNER line.
Example gate: run it against a saved PR body file.
It does not call a vendor API and does not prove the human read the diff.
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
SIGNER_RE = re.compile(
r"^SIGNER:\s*@?(?P<name>[A-Za-z0-9][A-Za-z0-9_-]{1,38})\s*$",
re.MULTILINE,
)
FORBIDDEN = {"unassigned", "none", "n/a", "agent", "bot", "model"}
def load_body(path: Path) -> str:
if not path.is_file():
raise SystemExit(f"missing PR body file: {path}")
return path.read_text(encoding="utf-8")
def find_signer(body: str) -> str | None:
match = SIGNER_RE.search(body)
if not match:
return None
return match.group("name")
def main(argv: list[str]) -> int:
target = Path(argv[1]) if len(argv) > 1 else Path("pr_body.txt")
body = load_body(target)
signer = find_signer(body)
if signer is None:
print("FAIL: no SIGNER: @handle line in pull request body")
return 2
if signer.lower() in FORBIDDEN:
print(f"FAIL: signer {signer!r} is a placeholder, not a human")
return 2
print(f"PASS: signer is {signer}")
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv))
保存一个示例 body 并运行检查两次,这样两条路径都可见。
printf 'SIGNER: UNASSIGNED\nALLOWLIST: src/\n' > pr_body.txt
python3 tools/check_signer.py pr_body.txt
# expected: FAIL
printf 'SIGNER: @alex\nALLOWLIST: src/\n' > pr_body.txt
python3 tools/check_signer.py pr_body.txt
# expected: PASS
把这些命令当作在你的环境中未执行的,直到你在一个一次性文件上跑过一次。这个脚本不能证明人类读了 diff;它只证明团队拒绝用一个空负责人合并。这是一个弱控制,但它仍然比随着免费会话消失的聊天更强。
如果你以后接入了 forge workflow,保持它同样小。下面的片段是一个提案,不是生产流水线,你应该在一个 fork 上跑过之后再在共享 main 上信任它。
# Proposal only — unexecuted in this article
name: signer-gate
on:
pull_request:
types: [opened, edited, synchronize]
jobs:
signer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Write PR body
env:
BODY: ${{ github.event.pull_request.body }}
run: printf '%s\n' "$BODY" > pr_body.txt
- run: python3 tools/check_signer.py pr_body.txt
一些共享实验室在 spike 便宜到可以丢弃时会是共享编码循环指向 MonkeyCode 的免费模型访问和免费服务器选项。披露:本文是作为 MonkeyCode 产品推广的一部分准备的。但仍然要保留签名者窗口,因为那个主机不能替代 PR 上具名的人类。
不要把免费主机当作持久的工具调用或 prompt 重试日志。会话状态可以消失,所以 Wiki 页面和 git 历史才是你保留的记录。不要在 Wiki 上编造配额、模型名或 uptime 承诺;只写 lab 日期、分支和三个 handle。如果免费服务器忙或不可用,你就暂停循环,不要把一个未签名的 diff 移到笔记本上。
把这个表格放在 Wiki SOP 下面,这样周五的你不会发明第四种结果。表格比部落记忆更能撑过长周末,而且给 merge captain 一些可以指向的而不是情绪的东西。
如果似乎有两行都适用,采取更严格的行动并在 Wiki 上写一句话解释为什么。在签名者窗口关闭之后不要重新打开 agent"只是整理一下测试"。第二个循环是新的一页、一个新的窗口和一次新的 ping,而不是隐藏在同一个 PR 里的延续。
这个 playbook 不会让模型更安全、更快或更准确,也不会恢复一个删除的会话。它只是在聊天死亡之后让所有权可见。Python 关卡可以被输入队友 handle 来欺骗,所以你仍然需要聊天 ping 和把名字放在坏 diff 上的社会成本。额外的延迟会惹恼那些想让 agent 在午饭前落地 main 的人——这是预期成本,而不是步骤中的缺陷。
如果已经有一个受监管的 CODEOWNERS 流程阻止了合并,第二个剧场关卡会隐藏真正的所有者,你不应该使用这个 SOP。你不应该把它用于已经有具名指挥官和记录在案的 bridge 的事故热修复。你不应该在任何主机(免费或付费)上把未签名的 agent 循环指向生产凭证。独立开发者仍然可以使用签名者行作为给未来自己的笔记,但两人分权不会存在,所以对于危险路径保持睡眠周期暂停。
如果你已经有一个用于 spike 的免费服务器,在下一个循环之前粘贴 Wiki 块,而不是等到周一回滚之后。