diff --git a/README.md b/README.md index 22a2bf9..f495f10 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ FirstMate(大副 / firstmate)是一个「agent distro」- 一个可移植的 | 2 | [如何提出一件活](chapters/02-proposing-a-task.md) | 一句话的请求怎么变成一件有明确项目、明确交付形态、明确验收边界的活,以及你怎么说能少走弯路。 | 已写 | | 3 | 船员与隔离工作副本 | 每个船员为什么要在自己的一份 git 工作副本里干活,并行的多件活为什么不会互相踩,出事时怎么看。 | 待写 | | 4 | no-mistakes 质检流水线 | 交付前那道自动化关卡都查什么,它自己修什么,什么情况下会停下来问人,以及问到人时该怎么回答。 | 待写 | -| 5 | PR 与合并权限 | 为什么默认必须你点头才合并,yolo 姿态放开了什么、没放开什么,以及红色 CI 为什么依然不能合。 | 待写 | +| 5 | [PR 与合并权限](chapters/05-pr-merge-authority.md) | 为什么默认必须你点头才合并,yolo 姿态放开了什么、没放开什么,以及红色 CI 为什么依然不能合。 | 已写 | | 6 | scout(侦察)任务与调查报告 | 什么时候该派侦察而不是直接开工,报告长什么样、存在哪里,以及一份报告为什么不等于动工的授权。 | 待写 | | 7 | backlog(工单)与船长决策 | 工单队列怎么记录在办和待办的活,一个等你拍板的决策为什么本身也是一张工单,以及它怎么被关闭。 | 待写 | | 8 | supervision(监督)与唤醒机制 | 大副怎么在不烧 token 的前提下盯住整支队伍,什么事件会把它叫醒,什么时候才该轮到你被打扰。 | 待写 | diff --git a/chapters/05-pr-merge-authority.md b/chapters/05-pr-merge-authority.md new file mode 100644 index 0000000..9dcae7a --- /dev/null +++ b/chapters/05-pr-merge-authority.md @@ -0,0 +1,105 @@ +# 第 5 章:PR 与合并权限 + +## 这一章讲什么 + +第 2 到 4 章沿着一件活的真实旅程走:第 2 章讲一句话怎么变成一件活,第 3 章讲船员在哪里干活,第 4 章讲质检流水线怎么查这件活。这一章接着往下走一关,也是这条「一件活的真实旅程」线(第 2 到 5 章)的最后一章:CI 转绿、PR 开好之后,谁有权说「合了」。 + +这一章只回答三个问题:为什么默认必须船长 / captain(你)点头才合并;`yolo` 这个姿态放开了什么、又没放开什么;以及红色 CI 为什么无论如何都不能合。再往后一关 - 什么时候该派 scout(侦察)而不是直接开工出活 - 留给第 6 章,这里不展开。 + +本章依据的权威文件,主要是 `AGENTS.md` 第 1 节的硬规矩二,以及第 7 节「Task lifecycle」下的「Selected delivery path and merge authority」小节。每个小节会指出具体出处。 + +## 规矩二:未经船长明确同意,不合并 PR + +`AGENTS.md` 第 1 节硬规矩二原文:「Never merge a PR without the captain's explicit word. A project's captain-approved `yolo` posture is the only standing relaxation for merge authority.」 + +翻成大白话:默认情况下,每一次合并都要你说了算,大副 / firstmate(你唯一的对话对象)自己不会拍板。唯一一种能常态化放开这道关卡的方式,是你为某个项目批准过的 `yolo` 姿态 - 没有这条标准放松,大副每次都得停下来等你点头。 + +这本教程自己所在的这个仓库,就是一个还没开 `yolo` 的活例子:翻这个仓库自己的 PR 记录就能看到,第 1 章的 PR(#1)、第 2 章的 PR(#3)都是先等 CI 全绿,再各自等来一次单独的合并动作落进 `main`,而不是绿了就自动合并 - 这正是 `yolo` 关着的样子。这意味着你现在读的每一章,包括这一章本身,落地前都经过了同一件事:船长明确说一句话,大副才去合并。 + +## `yolo` 放开的是合并权限,不是别的 + +`AGENTS.md` 第 7 节「Task lifecycle」下的「Selected delivery path and merge authority」小节把这件事定得很死:「Delivery mode and `yolo` are orthogonal. `yolo` governs merge authority only: with it off, the captain approves every PR merge and every local-only landing; with it on, firstmate merges green, in-scope work itself.」 + +这句话里有两层意思,值得拆开看: + +**`yolo` 只管一件事 - 谁有权点头合并。** 它跟交付路径(第 2 章讲过的 `no-mistakes`、`direct-PR`、`local-only` 三选一)是两个正交的维度。关着,你批准每一次 PR 合并、也批准每一次 `local-only` 的本地落地;开着,大副对**绿色、且在授权范围内**的活自己合并。它不改变质检流水线本身怎么跑、查什么、什么时候停下来问人 - 那些是第 4 章讲的事,`yolo` 一个字都不碰。 + +**`yolo` 也不能让红灯变绿。** 「firstmate merges green, in-scope work itself」这句话里的「green」不是修饰词,是前提条件。`yolo` 放开的只是「谁来按下合并那个按钮」,它不授权大副去动质检流水线本身的判定标准,更不能把一个还没转绿的检查当成过了。 + +## 红色 CI 为什么永远不能合 + +同一节接着写:「Never merge a red PR under either setting unless a current explicit captain instruction names the single GitHub check waived through `fm-pr-merge.sh --allow-red`; that attended-only waiver still requires every other check green.」 + +也就是说,不管 `yolo` 开没开,红色 PR 默认都不能合。唯一的例外窄得几乎不算例外:你在**当下**明确点名说要放行**某一个具体的** GitHub 检查项,大副才能用 `fm-pr-merge.sh --allow-red` 去豁免那一项 - 而且这个豁免只能人工触发,豁免的也只是你点名的那一项,其余每一项检查依然必须是绿的。 + +这条规矩同时挡住了两种常见的误会: + +- **「`yolo` 开着,是不是就可以先合再说?」** 不行。`yolo` 只是免去了「等你点头」这一步,红色 CI 依然是硬拦截,跟 `yolo` 开没开无关。 +- **「船长说了『合并吧』,是不是就可以无视 CI?」** 也不行。你的话解决的是「谁批准合并」这件事,不解决「这个 PR 现在是不是绿的」这件事 - 两者是分开的必要条件,都满足才能合并。 + +同一节还补了一句,跟 `yolo` 关系不大但同样重要:「Destructive, irreversible, and security-sensitive merges still escalate.」破坏性、不可逆、涉及安全的合并,即使 `yolo` 开着,依然要交给你 - 这条跟第 1 章讲的规矩二背后同一条道理(合并是这条流水线上唯一真正不可逆的一步)是一回事,只是这里把它写进了 `yolo` 这一节,专门堵上「`yolo` 开了是不是什么都能自动做」这个想当然的推论。 + +## 从这个仓库自己的合并记录里看两件事 + +规则讲完了,落到这个仓库自己的 PR 记录上更清楚 - 这些是公开、可核对的合并状态,不涉及任何私有运行状态。 + +**第一件事:合并需要两个条件同时满足,缺一个都不会发生。** 第 2 章的 PR(#3)现在已经合并进了 `main`。按规矩二,这只可能发生在 CI 全绿、并且船长明确说了话之后 - 具体是哪一句话、当时聊了什么,教程不去猜,因为那类过程记录不在这个仓库的追踪范围内,猜了就是编。第 3 章的 PR(#4)截至本章写作时依然开着、还没合并,即便它的 CI 也是绿的。这正是「两个条件都满足才合并」的活证据:光绿不够,光有人说话也不够,两者都在,合并才发生。 + +**第二件事:这条规矩不因为项目而改,只因为 `yolo` 而改。** 这个仓库本身没有开 `yolo`,所以上面两个 PR 走的都是同一条标准路径:等 CI 绿,等船长一句明确的话,才有一次单独的合并动作。`yolo` 开着时会跳过「等话」这一步,但跳不过「等绿」那一步 - 上一节讲的「红色 CI 永远拦得住」,跟 `yolo` 开没开无关,就是这个道理。 + +## 动手练习 + +下面两个练习都是**只读**的:只是让大副读取信息、做推理并汇报,不会创建工单、不会派出真正的船员、不会做任何合并或推送,也不会做任何不可回退的操作。你随时可以停下。 + +做练习前,先在你的 FirstMate 目录里启动一个 primary 会话,这样你面前的这个 agent 就是你的大副。 + +### 练习 1:拿几种组合,推演它会不会合并 + +对大副说: + +> 大副,我要试一下你在合并这一步的判断逻辑,不是真的要你合并任何东西。请你分别回答下面几种假设情形,你会不会合并,为什么 - 每种都要点出你依据的是哪条规矩: +> 1. 这个项目 `yolo` 开着,PR 的某一项 GitHub 检查现在是红的,我什么都没说。 +> 2. 这个项目 `yolo` 关着,PR 全绿,我刚说了一句「合并吧」。 +> 3. 这个项目 `yolo` 开着,PR 全绿,但这次合并涉及一次破坏性操作(比如需要强推)。 +> 4. 这个项目 `yolo` 开着,PR 除了一项检查全绿,我刚明确说「那一项检查可以跳过,其他不动」。 +> 这只是一次推演,不要真的去查任何真实 PR,也不要执行任何合并或推送相关的命令。 + +**预期会看到什么** + +- 情形 1:它会说不合并,因为红色 CI 挡住合并,跟 `yolo` 开没开无关。 +- 情形 2:它会说会合并,并指出这正是 `yolo` 关着时的标准路径 - CI 绿加你的明确同意两个条件都满足。 +- 情形 3:它会说这类破坏性操作依然要交给你,`yolo` 不覆盖这一类合并。 +- 情形 4:它会说这种情况下可以用 `fm-pr-merge.sh --allow-red` 只豁免你点名的那一项检查,但会强调这个豁免只能由你的当下明确指示触发,且其余检查依然必须是绿的。 +- 每种情形它都会点出出处,主要是 `AGENTS.md` 第 1 节硬规矩二和第 7 节「Task lifecycle」下的「Selected delivery path and merge authority」小节。 + +**怎么判断做成了** + +两条都满足才算:四种情形的判断都对得上上面的规则,尤其是情形 1 和情形 3 - 它没有因为 `yolo` 开着就默认合并;以及 - 最关键的 - 它**没有执行任何真正的合并、推送,或者查询真实 PR 状态的命令**,只是在推演。 + +文件层面的验证办法跟前几章一样,**前后对比**:提问之前在 FirstMate 目录里跑一次 `git status --short` 和 `git diff HEAD`,把两份输出都留着;问完之后再各跑一次,两次应该完全一样。`data/`、`state/`、`config/`、`projects/`、`.no-mistakes/` 是大副私有的运行状态,被 gitignore 掉了,这两条命令本来也看不见,会话期间写这些不算数。 + +如果它在情形 1 或情形 3 里说会直接合并,或者它去真的执行了合并、推送类命令,那就是没做成。 + +### 练习 2:拿这个仓库自己的 PR 记录核对合并条件 + +对大副说: + +> 大副,去查一下这个仓库(learn-firstmate)第 2 章的 PR 和第 3 章的 PR 现在分别是什么状态 - 有没有合并进 `main`、CI 是不是绿的,只读查询就行,不用问我。然后告诉我:如果第 2 章的 PR 已经合并了,按规矩二这必然意味着当时发生过什么;如果第 3 章的 PR 还没合并,即使它的 CI 也是绿的,那又是因为什么条件还没满足。查不到或不确定的地方就直接说查不到,不要编。不要改任何文件,也不要派任何船员,也不要执行任何合并或推送相关的命令。 + +**预期会看到什么** + +- 它会先去看实际的 PR / CI 状态,而不是凭印象回答。 +- 关于第 2 章的 PR:它会说,既然这个仓库 `yolo` 关着而它已经合并了,那必然是 CI 先绿、船长又明确说了话,两者都发生过 - 但它不会替船长编造当时具体说了哪句话,因为那类过程记录不在这个仓库的追踪范围内。 +- 关于第 3 章的 PR:它会说,CI 绿不等于合并条件已经满足,还缺船长的明确点头这一步,所以还没合并,这跟 CI 是不是绿的是两件事。 + +**怎么判断做成了** + +两条都满足才算:它的判断依据是真的去查过的 PR / CI 状态,而不是编造的对话细节;并且它没有执行任何合并、推送类命令。 + +文件层面的判断跟练习 1 一样:提问前后各跑一次 `git status --short` 和 `git diff HEAD`,两次输出应该一样,并且没有新开的船员会话窗口。 + +如果它替船长编出了某句具体的话,或者把「CI 绿」直接当成「已经合并」的证据,那就是没做成。 + +## 下一章 + +第 6 章讲 **scout(侦察)任务与调查报告**:什么时候该派侦察而不是直接开工,报告长什么样、存在哪里,以及一份报告为什么不等于动工的授权。