|
| 1 | +# 派发与收集运行细则(references —— 按需加载) |
| 2 | + |
| 3 | +出处:主文件「派发」「收集」。原则住在主文件;本表是派发云卡、接手死 dev、处置停 |
| 4 | +摆/重放/失报那一刻查阅的操作细则。⛔ 不引用 issue 编号。 |
| 5 | + |
| 6 | +## 云卡(`mode:cloud`)四课 |
| 7 | + |
| 8 | +一次性云卡用 `create_session`,⛔ 不用 create_trigger+fire(维护者 2026-08-07 拍 |
| 9 | +板;trigger 流只留给定时/重复型)。 |
| 10 | + |
| 11 | +1. **授权面随 source,不随环境**:trigger 拉起的会话没有仓库授权(只能只读勘察); |
| 12 | + `create_session` 带 `source_url` 的会话出生即持推送授权。同时带 |
| 13 | + `outcome_branch`(= 认领分支)、显式 `model`(trigger 流不可指模型)、`title` |
| 14 | + (以车道名开头,⛔ 不叫 os-dev;形如 `⚡ <车道> #<单号> <短语>`)。 |
| 15 | +2. **派发词必带自驱条款**(云会话回合一结束就停摆等 poke,不写这条 dev 会停在中期 |
| 16 | + 汇报或提问处):⛔ 不为提问/中期汇报结束回合;开放选择按裁决与评估轴自裁记入终报 |
| 17 | + open_questions;合法回合终点只有 (a) 推送完成 + 终报,或 (b) 硬阻塞详报。 |
| 18 | +3. **交付通道**:dev 自开 draft PR(`Fixes #<n>`,正文含验证记录)+ 终报以 issue 评 |
| 19 | + 论(os-dev-report 标记)交付;未 attach 的姊妹仓够不着,跨仓跟进卡由 PM 代立。 |
| 20 | + trigger 拉起的定时会话维持降级通道:推送 outcome branch + 终报走最后一条会话消 |
| 21 | + 息,PM 代开 draft PR。 |
| 22 | +4. **云卡 draft PR 一存在,立即 `subscribe_pr_activity` —— 硬步骤**:未订阅的云卡 |
| 23 | + PR 是轮询负债,订阅把感知从巡检周期缩到秒级。 |
| 24 | + |
| 25 | +监控与转向:`get_session` 读实时状态(IDLE + 分支未推送 = 停摆待 poke);投递消息 |
| 26 | +用绑定会话的 poke 触发器(`create_trigger` 带 `persistent_session_id` + |
| 27 | +`fire_trigger` + 用后即 `delete_trigger`);巡检退为兜底心跳,每轮先核订阅已覆盖哪 |
| 28 | +些面、只补盲区(会话停摆、未开 PR 的分支、姊妹仓动静)。CCR 云会话不注册跨会话消息 |
| 29 | +roster —— `ListAgents` 列不到、`SendMessage` 直投 not-reachable 是设计而非故障(维 |
| 30 | +护者 2026-08-11 裁定:事件驱动架构即长期方案),⛔ 不复测 roster 路径。 |
| 31 | + |
| 32 | +## 接手中断的 dev(worktree 接手协议) |
| 33 | + |
| 34 | +先试 SendMessage 复活(从 transcript 带全部上下文恢复),resume 不可用才接手。⛔ |
| 35 | +不重跑原派发词 —— 新 agent 带四条增量: |
| 36 | + |
| 37 | +- worktree 已存在,⛔ 不要新建,`cd` 进去接着做(第二个 worktree 会劈开工作); |
| 38 | +- 先读全部既有提交与未提交改动,逐 hunk 决定保留或修正 —— 既不推倒重来也不盲信(死 |
| 39 | + agent 从未回报,它的一切都未经验证); |
| 40 | +- 把死 agent 没跑完的验证**完整重跑**并报真实输出(中断的运行没有留下任何测试证 |
| 41 | + 据); |
| 42 | +- assignee、认领评论、分支**全部不动** —— 这是既有认领的延续,不是新认领;认领评论 |
| 43 | + 记录接手,不被替换。 |
| 44 | + |
| 45 | +## 停摆复位梯度 |
| 46 | + |
| 47 | +停摆的 subagent 永不自愈 —— 携带**任务中途状态**的完成通知本身就是停摆信号,立刻 |
| 48 | +SendMessage 附执行姿态句(「前台(阻塞)同步执行全部步骤,中途不停止、不把构建/测 |
| 49 | +试挂到后台等唤醒」),⛔ 不等任何静默阈值 —— 阈值是给「没有回答」的,不是给「回答说 |
| 50 | +我停了」的。**每次复位比上一次更具体**(原样重发同一句话不算一次复位):① 复述执行 |
| 51 | +姿态 → ② 点名下一个工具调用 + 明令禁止后台等待 → ③ 第三次停摆判 unreliable,按接手 |
| 52 | +协议重派到该分支。自己挂的定时器不会唤醒自己。长验证管线的派发/接力词写明前台姿 |
| 53 | +态。生产侧条款在 os-dev 定义 —— 这里是消费侧兜底,⛔ 不能写成「派发词写全了就可以不 |
| 54 | +探」。 |
| 55 | + |
| 56 | +## 通知重放去重 |
| 57 | + |
| 58 | +通知可以形态完全正常、报告完整正确,而只是同一份东西的第 N 次重放(monitor 按自己 |
| 59 | +的 deadline 触发)。**先算身份,再决定读不读内容**:去重三元组 |
| 60 | +`(issue, 分支, PR head sha)` + 通知自报的守护对象;与已验收那份逐项相同 ⇒ 台账记 |
| 61 | +「重放,首达时间 T」即结束,⛔ 不重新验收、不重读 diff、不重复 ACCEPT。⛔ 到达不读 |
| 62 | +作「还活着」(活着的判据只有探针回包),不到达也不读作「已死」(判死只认三类正当依 |
| 63 | +据)。对面自报守护对象是「变便宜」,不是去重的前提 —— 没自报就用三元组自己算。 |
| 64 | + |
| 65 | +## 直接验收兜底(报告丢失 ≠ 验收停摆) |
| 66 | + |
| 67 | +同时满足 (a) draft PR 已存在且 CI 全绿、(b) 探活确认已死或 ≥2h 无任何推送、(c) 报 |
| 68 | +告未达 ⇒ PM 直接按 PR 验收:逐文件核对 diff 与认领申报的文件面,对照 `origin/main` |
| 69 | +复核 PR 正文的前提声明与验证叙述,复核清单其余判据不减。顺序保护:agent 可能还活着 |
| 70 | +时**先探活、后翻 ready**(抢先翻会与它的收尾推送竞态)。死因可以是舰队级的(全账号 |
| 71 | +断粮同杀所有在飞 dev,探活半边同时不可用)—— 此时取 (a)+(c) 照常收口,PR body 就是 |
| 72 | +报告。「推分支 → 开 draft PR → 立即交报告」是保险不是效率优化,它住在 os-dev 定义 |
| 73 | +的 Definition of done,派发令只带增量。 |
| 74 | + |
| 75 | +## 派发词构造细则 |
| 76 | + |
| 77 | +⛔ 默认不整段粘贴 issue 正文 —— 让 dev 自己读 GitHub 全文与全部评论(premise-first |
| 78 | +本来就要求),并**必须**要求 dev 自查正文完整性:长正文经工具读取可能被静默截断, |
| 79 | +截断风险随「自己读」转移给 dev,这条自查是风险转移的对价,不是客套。派发词只带增 |
| 80 | +量: |
| 81 | + |
| 82 | +- **三分区,措辞决定 dev 敢不敢证伪**:「裁决(不可重裁)」= 维护者/PM 已拍板的方 |
| 83 | + 向与语义 —— dev 执行,不重开;「PM 机制假设(须实测,鼓励证伪)」= PM 对代码机制 |
| 84 | + 的判断 —— dev 动手前验证,证伪了照实报告并按裁决意图换实现路径,⛔ 不许为了顺从假 |
| 85 | + 设硬做;「PM 建议的路线(可选,实测优先)」= PM 顺手给的实现选项/断言写法/排除面 |
| 86 | + —— dev 有更好的就换,⛔ 不得因为「派发令写了」而照做。凡「我觉得可以这样」的一律降 |
| 87 | + 到第三块 —— 不分区的派发令里,机制假设穿着裁决的衣服,两个方向都是返工。 |
| 88 | +- **标准非协商条款 ⛔ 不抄进派发词** —— 已一次性下沉进 `.claude/agents/os-dev.md`。 |
| 89 | + 角色文件优先级是实测事实:派发词与角色文件冲突时角色文件胜,所以对每张卡都成立的 |
| 90 | + 无条件条款只能住在角色文件、错了就修那里;逐卡变量走模板占位符与三分区,⛔ 不靠派 |
| 91 | + 发词临时覆盖角色文件默认值。 |
| 92 | +- **清单、路径、行号在派发那一刻从树上取**,⛔ 不从卡片/上次派发/记忆抄(门禁清单单 |
| 93 | + 班之内就会过期)。取数:`node scripts/pm/dispatch-gates.mjs <改动路径>…` 产出本卡 |
| 94 | + 该跑的门禁族,填进派发令;取数的是 PM 不是 dev —— dev 只跑被点名的几族,全 farm |
| 95 | + 归 CI 跑一次,点名的准确性从此是 PM 独担的。卡片或分诊评论里的行级断言,转述进派 |
| 96 | + 发令前必须自己重验一遍。 |
| 97 | +- **文件面写两句**:「预期落点是 X;若实测表明真正的生产者在别包,报备后按生产者侧 |
| 98 | + 修(落点与理由写进报告和 PR 正文),⛔ 不在消费者侧打补丁」—— 只写一个路径名的派 |
| 99 | + 发令,是要求 dev 在守约与修对之间二选一。跨包常常等于跨车道,PM 侧的对价是事后补 |
| 100 | + 跨座位声明。 |
| 101 | +- **Same-day churn 进派发词**:派发时 `git log origin/main --oneline -20 -- |
| 102 | + <paths>` 见到当天合并 ⇒ 加一行「基于合并后的代码工作,issue 引用的片段可能已变, |
| 103 | + 先核对当前 main」(dev 的 worktree 从 origin/main 切出后不会自己更新)。**在飞重 |
| 104 | + 叠也要拦截**(churn 行只覆盖派发瞬间):每轮读 main 新落 PR 与每个在飞派发的申报 |
| 105 | + 文件面求交,相交立即警告四句 —— 合 main 重跑测试矩阵、读对方 diff 重划边界、只补 |
| 106 | + 它没覆盖的部分、被完全覆盖就停下回报 ⛔ 不硬造 diff。晚一轮 = 一次返工。 |
| 107 | +- **翻转公开语义的裁决随卡带全仓 pin 清扫**,两句缺一不可:① grep 错误码/错误消息 |
| 108 | + **全仓扫描**同语义 pin,一轮翻完,不要只改本包(旧立场的 pin 住在被改包之外的消费 |
| 109 | + 层);② 翻转后的 pin 必须继续承重 —— 断言新语义的**实质**(行数、译文、状态码), |
| 110 | + 不是「旧断言已删」;真正非法形状的拒收断言**逐字保留**,被守护的面永不缩水。丢第 |
| 111 | + 二句,「全仓翻完」退化成「全仓删光」,绿而无值。 |
| 112 | +- **条件性标准条款,命中判据才抄,不命中就省掉别硬套**: |
| 113 | + - 多实现面组件(同一契约 ≥2 个实现面)⇒ 「测试放在**未来的分叉会被抓住的地方**, |
| 114 | + 进共享一致性覆盖,不是独立测试文件」;不变量形:与 `find()` 给出相同行集,或以 |
| 115 | + `INVALID_FILTER` 拒收 —— 不允许有第三种、更安静的答案。 |
| 116 | + - 新增/改写拒收类用例 ⇒ 「最低断言错误的 `code` 与 `status`(ADR-0112 信封); |
| 117 | + `toThrow()` / `rejects.toThrow()` 单独使用不构成拒收测试;措辞本身是契约时首句 |
| 118 | + 断言**加在** `code`+`status` 之上;只约束新写/改写的用例,不回填存量」。 |
| 119 | + - 改过滤/谓词语义 ⇒ 把 `references/compile-surfaces.md` 的编译面清单**按其复核串 |
| 120 | + 重验后逐面抄进派发令**(⛔ 不凭记忆),并带:「每一面都必须在 PR 正文有一个结 |
| 121 | + 论:已改 / 本就合规(证据)/ 明确不在范围(理由);⛔ 静默略过 —— 评审把没提到 |
| 122 | + 的面读作漏掉的面」。防的不是做错,是做对了一部分然后以为做完了。 |
| 123 | +- **Premise-first 写明**:issue 正文是线索不是规格,先对 origin/main 验前提; |
| 124 | + `premise_still_valid: false` + 无 PR 是合法且常常有价值的交付 —— 派发词预设 |
| 125 | + issue 为真,就把好运行变成表面抗命。 |
0 commit comments