From 4881123a2b64bb09a4265f8060c117bebf934879 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 12 Aug 2026 11:20:04 +0000 Subject: [PATCH 1/2] =?UTF-8?q?docs(pm-dispatch):=20cloud=20publish-fallba?= =?UTF-8?q?ck=20protocol,=20probe-control=20validity,=20type-check-debt=20?= =?UTF-8?q?dispatch=20clause=20=E2=80=94=20one=20shift's=20measured=20fail?= =?UTF-8?q?ures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A full shift of measured dispatch failures, distilled in place per the principles-only standard (no issue-ID citations in operative text): - dispatch-runbook: new '云 dev 的 GitHub API 不可达 — 发布回落协议' section. Push credential and API reachability fail independently (org without the Claude GitHub App connected: 5 of 5 cloud devs pushed branches, 0 opened PRs, one idled ~2h in need_input). Four hard rules: full brief travels in the prompt (comment stays as public record), every cloud dispatch carries a publish-failure fallback clause, PM opens the PR reading the changeset from the branch diff (never ls-tree | head -1), get_session status is not completion. Names the org-admin App connection as the real fix that retires the whole section. - dispatch-runbook: conditional dispatch clause for tests entering type-check DEBT/EXEMPT packages — name check:type-check-debt with a built closure (pnpm typecheck is structurally green there); two anti-patterns: no ledger raise to admit the PR's own file, no --lower of other packages' info lines. Three PRs hit this gate in one shift; the errors it caught included real API misuses vitest cannot see. - platform-readings: merged branches are auto-deleted and therefore invalid as positive controls for branch probes; MCP traps grow a third — union totalCount reads like queue depth, and freshly-filed cards can land unlabeled (write-then-read-back applies to filing). - SKILL.md (line-ratchet-neutral at 686): cloud lesson ① now carries push-auth ≠ API-reach with a pointer to the fallback protocol; the same-file-serial exemption gains the per-hot-file editor cap and the reading that it guards concurrent editors, not queued PRs (next card is dispatchable when the prior dev session ends); lane candidates are re-read from GitHub every round, never dispatched off a carried list; conditional-clause summary lists the debt gate. Paid for by compressing passages whose detail already lives verbatim in references/. Gates: check:pm-skill-ratchet, check:pm-skill-id-lint, check:skill-frame-sync, check:skill-compatibility, check:nul-bytes, check:empty-changeset, check:doc-anchors all green. check:skill-frame-freshness fails its own self-test identically on clean main (pre-existing, reported separately). Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_012Wtgqp5ufgBmFDakHEMegd --- .claude/skills/pm-dispatch/SKILL.md | 64 +++++++++---------- .../references/dispatch-runbook.md | 32 ++++++++++ .../references/platform-readings.md | 15 +++-- 3 files changed, 75 insertions(+), 36 deletions(-) diff --git a/.claude/skills/pm-dispatch/SKILL.md b/.claude/skills/pm-dispatch/SKILL.md index d8694a564d..3a94e147ed 100644 --- a/.claude/skills/pm-dispatch/SKILL.md +++ b/.claude/skills/pm-dispatch/SKILL.md @@ -135,9 +135,8 @@ UI 创建并勾 GitHub 连接器、UI 钉模型(会话内 create_trigger 的Rout 证据的零实现停手是好产出,不当返工计)。**裁决明令的动作实施中测出对向事实** ⇒ 照裁决字面执 行、被打断行为的 pin 反转为拒绝 pin(不是删除)、⛔ 同 PR 不做任何 promote/回退、冲突立 成 `needs-user-decision` 卡、该 PR 不挂 auto-merge 留异议窗口。 -- **spec 改动的 fixture triage 必须跑消费包测试**(A 包的改动可让 B 包的 fixture 反着断言 - ,spec 范围内任何 sweep 都看不见)—— 动契约面的派发令点名消费包测试清单,报告要有各消费包真实 - 读数。 +- **spec 改动的 fixture triage 必须跑消费包测试**(A 包的改动可让 B 包的 fixture 反着断言, + spec 内的 sweep 看不见)—— 动契约面的派发令点名消费包测试清单,报告要各消费包真实读数。 ## 多仓协调(五条规则) @@ -319,17 +318,19 @@ UI 创建并勾 GitHub 连接器、UI 钉模型(会话内 create_trigger 的Rout ### 候选与批次 -**整车道一次读全,本地求交**(维护者 2026-08-11 接受):`list_issues` 带 `labels: [domain:X]` + -最小字段一次拿回全车道 open 集,各状态本地求交 —— 按单一 pm 状态切片的查询看不见其它状态,是结 -构性盲区。候选 = open、未 assign、无`needs-user-decision`;已排队父单的 open sub-issue 自动是 -候选(`pm:epic` 父单的子树除外)。**每张候选读全文 + 全部评论**(裁决落在评论区,跳过评论就是跳 +**每轮整车道重读、一次读全,本地求交**(维护者 2026-08-11 接受):`list_issues` 带 +`labels: [domain:X]` + 最小字段一次拿回全车道 open 集,各状态本地求交 —— 单一 pm 状态切片的查 +询看不见其它状态;⛔ 不拿上轮/检查点清单当派发输入(实测两次漏卡)。候选 = open、未 assign、 +无`needs-user-decision`;已排队父单的 open sub-issue 自动是候选(`pm:epic` 父单的子树除外)。**每张候选读全文 + 全部评论**(裁决落在评论区,跳过评论就是跳 过裁决;评论还可能记着一半工作已交付);**派发前做 stale-premise check**(issue 描述的是立单当天 的仓 —— `git log --oneline -20 -- ` 花几分钟,不查则赔一次 agent-run)。 **批次独立性。** 一批内任两单不得可能碰同一个包/registry/barrel/spec schema;拿不准就串行。**同 文件单跨轮硬串行;延后不是搁置**(被延后那一刻就把已知的坑记到该 issue 上)。**维护者明示豁免同 -文件串行时,替代纪律四条**(豁免的是排队,不是防撞):① 文件面申报到**区域**级(函数/段落);② 开 -PR 前合一次 main;③ 兄弟卡落地后再合一次;④ 冲突交合并队列仲裁,⛔ PM 不手动排序;豁免不外溢。** +文件串行时,替代纪律四条**(豁免的是排队,不是防撞):① 文件面申报到**区域**级(函数/段落),同一 +热文件并发编写者设上限;② 开 PR 前合一次 main;③ 兄弟卡落地后再合一次;④ 冲突交合并队列仲裁, +⛔ PM 不手动排序;豁免不外溢,防的是并发**编写者**不防队列里的成品 PR —— 前一 dev 会话一结束即 +可派下一张同文件卡,⛔ 不等其 PR 落地。** 阻塞解除后给延后单重新定价**:派发前一单时带必答项「你的改动让 #X 变简单/变难/变得不必要还是无 影响?」,派发后一单前用这个回答重读它的选项与成本,⛔ 不沿用立单时那份(前后单共用同一契约或数 据表示时适用)。 @@ -411,7 +412,8 @@ dev 侧推分支要早 —— 远程分支是在飞工作最硬的证据。**Sta - **翻转公开语义的裁决随卡带全仓 pin 清扫**,两句缺一不可(全仓一轮翻完;翻转后的pin 断言新语义 的实质,真非法形状的拒收断言逐字保留 —— 丢第二句就退化成「全仓删光」)。**条件性标准条款命中 判据才抄**:多实现面 ⇒ 共享一致性覆盖;拒收用例 ⇒ `code`+`status` 最低断言;过滤/谓词语 - 义 ⇒ 编译面清单逐面申报(⛔ 静默略过)。 + 义 ⇒ 编译面清单逐面申报(⛔ 静默略过);测试进 type-check 债包 ⇒ 点名 + `check:type-check-debt`(债包 `pnpm typecheck` 结构性全绿)。 - **Premise-first 写明**:issue 正文是线索不是规格;`premise_still_valid: false` +无 PR 是合法 且常常有价值的交付 —— 派发词预设 issue 为真,就把好运行变成表面抗命。 @@ -424,11 +426,12 @@ Model tiering 显式传参);S 级但不机械(判断面在设计不在门禁)按 **云卡四课**(细则见 `references/dispatch-runbook.md`;一次性云卡用 `create_session`,⛔ 不用 create_trigger+fire —— 维护者 2026-08-07 拍板,trigger 流只留给定时/重复型):① 授权面随 -source 不随环境;② 派发词必带**自驱条款**;③ 交付通道 = dev 自开 draft PR + 终报以 issue 评论 -交付;④ **云卡 draft PR 一存在立即 `subscribe_pr_activity` —— 硬步骤**。云会话 `SendMessage` -not-reachable 是设计非故障(维护者 2026-08-11 裁定),⛔ 不复测。**接手中断的 dev**:先试 -SendMessage 复活,resume 不可用才走接手协议 —— ⛔ 不重跑原派发词;worktree 不新建;逐 hunk 读 -既有工作再决定;验证完整重跑;assignee/认领评论/分支全不动(既有认领的延续,不是新认领)。 +source 不随环境,且 **push 授权 ≠ GitHub API 可达** —— App 未接通的 org 里 dev 推得了分支、开 +不了 PR 读不了 issue:完整令随 prompt 携带 + 发布失败回落条款,回落协议见 runbook;② 派发词必 +带**自驱条款**;③ 交付通道 = dev 自开 draft PR + 终报以 issue 评论交付;④ **云卡 draft PR 一 +存在立即 `subscribe_pr_activity` —— 硬步骤**。云会话 `SendMessage` not-reachable 是设计非故障 +(维护者 2026-08-11 裁定),⛔ 不复测。**接手中断的 dev**:先试 SendMessage 复活,不可用才走接手 +协议(四条增量见 runbook;既有认领的延续不是新认领,⛔ 不重跑原派发词)。 ### 收集 @@ -453,15 +456,14 @@ SendMessage 复活,resume 不可用才走接手协议 —— ⛔ 不重跑原派 **失报与停摆的处置(细则见 `references/dispatch-runbook.md`)。** 三条原则: -- **停摆永不自愈**:携带任务中途状态的完成通知本身就是停摆信号,立刻 SendMessage 附前台执行姿 - 态句,⛔ 不等任何静默阈值(阈值是给「没有回答」的);复位走梯度,每次比上一次更具体,第三次停摆 - 判 unreliable 按接手协议重派。这里是消费侧兜底,⛔ 不能写成「派发词写全了就可以不探」。 +- **停摆永不自愈**:携带任务中途状态的完成通知就是停摆信号,立刻 SendMessage 附前台执行姿态句 + ,⛔ 不等静默阈值(阈值是给「没有回答」的);复位走梯度、逐次更具体,第三次停摆判 unreliable 按 + 接手协议重派。这里是消费侧兜底,⛔ 不能写成「派发词写全了就可以不探」。 - **通知重放先算身份再读内容**:去重三元组 `(issue, 分支, PR head sha)`,与已验收那份相同 ⇒ 记 「重放」即结束,⛔ 不重新验收不重复 ACCEPT;⛔ 到达不读作「还活着」,不到达也不读作「已死」。 - **直接验收兜底(报告丢失 ≠ 验收停摆)**:(a) draft PR 在且 CI 全绿 + (b) 探活确认已死 - 或 ≥2h 无推送 + (c) 报告未达 ⇒ 直接按 PR 验收(逐文件核对 diff 与申报文件面,对 - 照 `origin/main` 复核前提与验证叙述,复核判据不减);先探活后翻 ready。舰队级死因(全账号断粮) - 下取 (a)+(c) 照常收口,PR body 就是报告。 + 或 ≥2h 无推送 + (c) 报告未达 ⇒ 直接按 PR 验收(复核判据不减,细则见 runbook);先探活后翻 + ready;舰队级死因(全账号断粮)下取 (a)+(c) 照常收口,PR body 就是报告。 ### 复核 @@ -499,10 +501,9 @@ You are the reviewer of record —— **对 GitHub 核验,不对报告的自述 **入队与落地(细则见 `references/landing-operations.md`,落地窗口查阅)。** 原则: - **碰生成物的 PR,入队前先同步 + 整体重生成** —— os-regen 驱动会零冲突标记地**静默丢掉一侧改 - 动**,只有重生成才暴露;四步序已机械化(`bash scripts/pm/os-regen-merge.sh`:**先 commit - merge 再重生成**,顺序防锚点静默倒退与`gen:openapi` 假红两个陷阱);重生成后断言兄弟单条目与 - 上一单**实现体**仍在;清单当场读 `grep os-regen .gitattributes` ⛔ 不抄进派发令当常量;⛔ 禁 - 止为凑相等手改锚点文件,⛔ 不得要求 `baseRev == merge-base`(允许滞后)。 + 动**,只有重生成才暴露;四步序已机械化(`bash scripts/pm/os-regen-merge.sh`,**先 commit + merge 再重生成**,顺序陷阱见 landing-operations);重生成后断言兄弟单条目与上一单**实现体**仍 + 在;清单当场读 `grep os-regen .gitattributes` ⛔ 不抄进派发令当常量;⛔ 禁止为凑相等手改锚点。 - **跟到 MERGED 为止;入队后的看护归队列管家。** 车道 PM 管验收、首次入队(ACCEPT 后挂 6–9 分 钟 flip 定点核门禁 job 结论,绿即转 ready + 挂 auto-merge —— CI success webhook 不可靠, ⛔ 不坐等不忙轮询)、确认 MERGED(两个读数);落地窗口给关键 PR 挂`subscribe_pr_activity`( @@ -562,13 +563,12 @@ blockers**(三仓 `target:`之和,归零 = 三张板都空)。 是否应该设置一个1小时的定时以监测时间窗口已经解锁」)。检测读数、盲区与恢复 playbook 细则 见 `references/platform-readings.md`;常驻原则: -- **检测**:`ccusage blocks` 给窗口边界与燃烧率,但只有单容器视野、估成本不估套餐余量(没有任何 - 面向 agent 的接口暴露账号级剩余额度);**权威的墙信号是失败本身**——撞墙报文里的重置时刻在那 - 一刻可得、事前查不到,把它记下来。 -- **跨墙定时器**:拿到重置时刻 ⇒ 一发定点(reset + 缓冲)优先;没有 ⇒ 挂每小时cron Routine,⛔ ** - 不用 send_later 链** —— send_later 是 run-once、fire 后自禁用(平台文档),投进死窗口的那一发 - 是否被重试未实测且文档未承诺,按保守设计一次性链条可能断在它存在的意义上;第一枪成功 - 的 fire 跑恢复后**删除 cron**(幸存 cron 是孤儿定时器)。fired 文本照定时器写法纪律。 +- **检测**:`ccusage blocks` 给窗口边界与燃烧率,但单容器视野、估成本不估套餐余量;**权威的墙 + 信号是失败本身** —— 撞墙报文里的重置时刻在那一刻可得、事前查不到,把它记下来。 +- **跨墙定时器**:拿到重置时刻 ⇒ 一发定点(reset + 缓冲)优先;没有 ⇒ 挂每小时 cron Routine, + ⛔ **不用 send_later 链**(run-once、fire 后自禁用,一次性链条可能恰好断在断粮窗口里 —— 论证 + 见事实表);第一枪成功的 fire 跑恢复后**删除 cron**(幸存 cron 是孤儿定时器)。fired 文本照定 + 时器写法纪律。 - **恢复 playbook 链的是既有规则**:逐个探在飞云卡 → 直接验收兜底或 transcript 复活→ 重挂常规 巡检 → 照常跑轮;draft-PR-early 契约守住时零信息丢失。 diff --git a/.claude/skills/pm-dispatch/references/dispatch-runbook.md b/.claude/skills/pm-dispatch/references/dispatch-runbook.md index f1c90ce60c..acb62e33e8 100644 --- a/.claude/skills/pm-dispatch/references/dispatch-runbook.md +++ b/.claude/skills/pm-dispatch/references/dispatch-runbook.md @@ -38,6 +38,30 @@ branch-early、draft-PR 时点报告、transcript 复活与 worktree 接手协 roster —— `ListAgents` 列不到、`SendMessage` 直投 not-reachable 是设计而非故障(维 护者 2026-08-11 裁定:事件驱动架构即长期方案),⛔ 不复测 roster 路径。 +## 云 dev 的 GitHub API 不可达 —— 发布回落协议 + +**push 授权 ≠ API 可达,两者独立失败**:org 未接通 Claude GitHub App 时, +`create_session` 云 dev 推分支一切正常,而 PR/评论/issue 的每一次 API 调用都被 +org 策略拦下。失败**安静且昂贵**:dev 把活干完、发布不出去、停在 need_input 等 +人 —— 实测一班五张云卡五次全中:五条分支推出、dev 侧零个 PR、其中一张在 +need_input 空等近两小时。App 未接通期间,四条硬规则: + +- **完整派发令随 prompt 携带;issue 评论照发,但只作公共存档**。「⛔ 不整段粘贴 + issue 正文」的前提是 dev 读得到 GitHub —— API 不可达时前提不成立,prompt 是唯 + 一送达通道(实测 dev 报 comment text unreadable 后原地停摆)。 +- **每张云卡派发令带发布失败回落条款**:开不出 PR ⇒ ⛔ 不循环重试、⛔ 不丢弃 —— + 完整 PR 正文、完整 ``、本应立的卡的完整文本,全部放进最 + 后一条会话消息,并写明哪些自己发成功了。 +- **PM 代开 PR 时,changeset 从 dev 分支的 diff 读**:`git diff + origin/main...FETCH_HEAD -- .changeset/`;⛔ 不用 `git ls-tree .changeset/ | + head -1` —— 它给的是字母序第一个**存量** changeset,曾对两条不同分支给出一模一 + 样的无关文本。 +- **`get_session` 的状态不是完成度**:`review_ready` / `need_input` 只说明 dev + 停了,不说明有东西可复核 —— 分支(`ls-remote`)与 PR 独立核验。 + +整套回落是 App 未接通期间的代偿,不是长期方案 —— **org 管理员把 Claude GitHub +App 接到 org 上,这一节整体作废**;读到本节的维护者优先做接通,不维护绕行。 + ## 接手中断的 dev(worktree 接手协议) 先试 SendMessage 复活(从 transcript 带全部上下文恢复),resume 不可用才接手。⛔ @@ -129,6 +153,14 @@ SendMessage 附执行姿态句(「前台(阻塞)同步执行全部步骤,中途 重验后逐面抄进派发令**(⛔ 不凭记忆),并带:「每一面都必须在 PR 正文有一个结 论:已改 / 本就合规(证据)/ 明确不在范围(理由);⛔ 静默略过 —— 评审把没提到 的面读作漏掉的面」。防的不是做错,是做对了一部分然后以为做完了。 + - 往带 type-check DEBT/EXEMPT 台账的包新增/改写测试文件 ⇒ 派发令点名 `pnpm + check:type-check-debt`,并要求**先 build 依赖闭包**(不建则 exit 1 是 + missing-module 级联,不是台账读数)—— 这类包把自己的测试排除在 tsconfig 之外 + ,有的连 `typecheck` 脚本都没有,`pnpm typecheck` 全绿的同时测试层照样漂移 + (一班之内三张 PR 撞同一道门)。⛔ 两个反模式一并写进派发令:不许抬台账数字放 + 行本 PR 自己新增的文件 —— 那是给自己开的许可条;不许 `--lower` 别的包的 ℹ 信 + 息行。这道门的价钱花得值:实测一张 PR 的三条「类型错误」里两条是真实 API 误用 + (必填参数缺失),vitest 永远测不出来。 - **Premise-first 写明**:issue 正文是线索不是规格,先对 origin/main 验前提; `premise_still_valid: false` + 无 PR 是合法且常常有价值的交付 —— 派发词预设 issue 为真,就把好运行变成表面抗命。 diff --git a/.claude/skills/pm-dispatch/references/platform-readings.md b/.claude/skills/pm-dispatch/references/platform-readings.md index 4d56ca3c57..77b0d20107 100644 --- a/.claude/skills/pm-dispatch/references/platform-readings.md +++ b/.claude/skills/pm-dispatch/references/platform-readings.md @@ -43,13 +43,20 @@ 一气完成);重试对齐整点(REST core 整点重置)优于指数退避,⛔ 绝不忙轮询。 search 与 core 是独立配额,一侧打满另一侧可作退路;REST core 在共享身份下同样 会打满 ——「走 REST」≠「不限量」。 -- **MCP 参数两陷阱**:`list_issues` 多标签过滤是 **OR** 不是 AND(要 AND 走 REST - search 的 `label:a label:b`,或本地求交);`issue_write` 的 `labels` 是**整组替 - 换**不是追加 —— 不先读现值合并再写,会静默剥掉别的标签(状态机丢位);真追加走 - REST `POST /issues/{n}/labels`;写后照标签纪律回读。 +- **MCP 参数三陷阱**:`list_issues` 多标签过滤是 **OR** 不是 AND,并集的 + `totalCount` 读起来与队列深度一模一样,⛔ 不当队列读数 —— 探一个标签、`pm:*` 本 + 地数(要 AND 走 REST search 的 `label:a label:b`,或本地求交);`issue_write` + 的 `labels` 是**整组替换**不是追加 —— 不先读现值合并再写,会静默剥掉别的标签 + (状态机丢位);真追加走 REST `POST /issues/{n}/labels`;**新立卡的 labels 同样 + 会静默丢**,落成无 `pm:*` 的卡对每一张 sweep 都不可见 —— 立卡与改标签同样适用 + 「写后回读」。 ## 读数陷阱 +- **已合并的分支被自动删除,⛔ 不能当分支探针的阳性对照**:拿它作对照得到空输出, + 读起来像「探针工作正常、只是分支还没出现」,实际什么都没证明。可用的对照要**此 + 刻确认存在**:`git ls-remote --heads origin 'claude/*' | wc -l`(在飞车队恒 + >0),或一个当前 open 的 PR head。 - **读数四坑**:`cd X && cmd` 会短路(路径不存在时命令在当前仓继续执行,产出假读 数)—— 跨仓一律 `git -C `;`git grep -c | wc -l` 数的是文件数不是命 中数;裸名 grep 被幸存家族当子串命中 —— 退役核验带引号精确名,更硬的判据是查声 From 5787cea41cf0a824db62089d376aa214f920ff92 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 12 Aug 2026 12:11:50 +0000 Subject: [PATCH 2/2] =?UTF-8?q?docs(pm-dispatch):=20correct=20the=20cloud-?= =?UTF-8?q?403=20measurement=20to=20five=20of=20six=20=E2=80=94=20reachabi?= =?UTF-8?q?lity=20flipped=20mid-shift,=20and=20stale=20sessions=20don't=20?= =?UTF-8?q?inherit=20a=20new=20App=20install?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two corrections to the publish-fallback section, both measured: - The count was overstated as 5/5. The earliest dispatch (~05:25Z) opened its PR and filed its card unaided; every dispatch from ~08:00Z on got 403. Honest figure: five of six — and the sixth is load-bearing: it proves the API was reachable earlier the same day and STOPPED, so the diagnosis is 'changed mid-shift', not 'never configured'. The section now says to ask 'when did it change', not 'was it ever set up'. - Measured from this very session after the maintainer connected the App: long-lived containers still 403 on API reads/writes ('not enabled for this session') while git push works — existing sessions do not inherit a new installation; only freshly created sessions pick it up. Recorded as boundary ① so nobody reads an old container's 403 as 'the connection didn't take'. Retirement call: the section stays, dormant while the App is connected (boundary ②) — reachability flipped once within a single shift, the section lives in references/ (zero ratchet cost), and the diagnostic shape is exactly what a future 403 reader needs first. The closing line no longer implies deletion on connection. Gates re-run: check:pm-skill-ratchet (686/686), check:pm-skill-id-lint, check:skill-frame-sync, check:skill-compatibility, check:nul-bytes, check:empty-changeset all green. origin/main merged in (no skill-file conflicts). check:skill-frame-freshness stays pre-existing red on main, tracked separately. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_012Wtgqp5ufgBmFDakHEMegd --- .../pm-dispatch/references/dispatch-runbook.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.claude/skills/pm-dispatch/references/dispatch-runbook.md b/.claude/skills/pm-dispatch/references/dispatch-runbook.md index acb62e33e8..29053e12c8 100644 --- a/.claude/skills/pm-dispatch/references/dispatch-runbook.md +++ b/.claude/skills/pm-dispatch/references/dispatch-runbook.md @@ -43,8 +43,10 @@ roster —— `ListAgents` 列不到、`SendMessage` 直投 not-reachable 是设 **push 授权 ≠ API 可达,两者独立失败**:org 未接通 Claude GitHub App 时, `create_session` 云 dev 推分支一切正常,而 PR/评论/issue 的每一次 API 调用都被 org 策略拦下。失败**安静且昂贵**:dev 把活干完、发布不出去、停在 need_input 等 -人 —— 实测一班五张云卡五次全中:五条分支推出、dev 侧零个 PR、其中一张在 -need_input 空等近两小时。App 未接通期间,四条硬规则: +人 —— 实测一班六张云卡中五张:分支照推、dev 侧开不出 PR,其中一张在 need_input +空等近两小时;**最早一张(~05:25Z)自己开出了 PR、立了卡,~08:00Z 起的派发全部 +403** —— 可达性是**班中翻转**的,不是从未配置,诊断先问「什么时候变的」,不问 +「有没有配过」。API 不可达期间,四条硬规则: - **完整派发令随 prompt 携带;issue 评论照发,但只作公共存档**。「⛔ 不整段粘贴 issue 正文」的前提是 dev 读得到 GitHub —— API 不可达时前提不成立,prompt 是唯 @@ -59,8 +61,12 @@ need_input 空等近两小时。App 未接通期间,四条硬规则: - **`get_session` 的状态不是完成度**:`review_ready` / `need_input` 只说明 dev 停了,不说明有东西可复核 —— 分支(`ls-remote`)与 PR 独立核验。 -整套回落是 App 未接通期间的代偿,不是长期方案 —— **org 管理员把 Claude GitHub -App 接到 org 上,这一节整体作废**;读到本节的维护者优先做接通,不维护绕行。 +整套回落是 API 不可达期间的代偿,不是长期方案 —— **修复是 org 管理员把 Claude +GitHub App 接到 org 上**,读到本节的维护者优先做接通,不维护绕行。两个边界:① +**存量会话不继承新接通的 App**(实测:接通后长命容器的 API 读写仍 403,报文明说 +not enabled for this session;git push 照常)—— 接通后新建的会话才拿到,别拿旧容 +器的 403 判「接通没生效」;② 本节在 App 接通期间**休眠不删除** —— 可达性在一班 +之内翻转过一次,再见 403 先认这个形状。 ## 接手中断的 dev(worktree 接手协议)