docs(os-dev): PR 收尾清单增补 skip-changeset 硬步骤,以回读 PR labels 为闭环 - #5650
Merged
Conversation
测试-only / 工作流-only / `.claude/`-only 的 PR 不写 changeset,靠 `skip-changeset` 标签豁免 Check Changeset。此前收尾清单对这一步只字未提,dev 在 PR 正文「声明」了 标签却没有真正挂上,#5533/#5538 两例各烧一轮门禁红并由 PM 手工兜底 —— 「声明了 ≠ 执行了」正是 declared ≠ enforced 的 agent 版。 新增条目把它写成与「PR 正文以 Fixes 开头」同级的硬步骤,并按实测校正了三处认知: - 没有任何自动化会替你挂:`.github/labeler.yml` 九条规则里没有 `skip-changeset`, 2026-08-05 六例(#5533/#5538/#5542/#5624/#5642/#5645)的该标签全部来自 agent, `github-actions[bot]` 一次都没挂过 —— 它只负责 `size/*`、`documentation`、 `tests`、`ci/cd`。 - 只「加一个标签」,不要整集写入:整集写入会把 bot 刚挂的 `size/*` / `documentation` / `tests` 抹掉(#5533/#5538/#5642/#5645 的 agent `unlabeled` 事件即此),反向也成立 —— #5533 的标签 15:46:44 落、15:46:45 就被 `github-actions[bot]` 的写入抹掉,只活了一秒。 - 闭环是回读而不是 POST:Check Changeset 在 PR 打开后数秒就实时读一次标签 (#5580),`opened` run 通常早于标签落地 —— #5542 的 dev 做对了全套,仍留下 一条红 `opened` run,之后每一次 run 才被标签豁免。所以要在 bot 平息后回读 标签、并把读到的列表写进报告。
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
本 PR(#5650)自己按新硬步骤执行时,实测结果与原措辞相反:标签 22:03:54 落地, `opened` run(workflow run 31051251795,创建于 22:03:38)的 Check Changeset job 直到 22:04:35 才启动并做实时标签回读 —— 早于回读 41 秒落地的标签被读到,该 run 直接 **success**,并非预设的红。 于是这一句改为如实描述竞态:首 run 的颜色取决于 runner 启动耗时与 POST 落地 的先后,两个方向都有实例(#5542 红、#5650 绿)。指导语随之从「预期会红」改为 「尽快落标签,把首 run 的颜色当信息而不是自己的判决」。 预设方向被自己的实测证伪时如实记录,而不是让措辞压着实测走。
os-zhuang
marked this pull request as ready for review
August 5, 2026 22:19
This was referenced Aug 5, 2026
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Aug 6, 2026
…ack-ai#5683) `Check PR Size` 与 `Auto Label` 都用**整集 PUT**(`PUT /issues/{n}/labels`) 写标签,不是新增 POST。源码实测(非文档推断): - `codelytv/pr-size-labeler@v1.10.4` `src/github.sh:68-91`:GET 读 PR 标签, grep 掉自己那套 size 家族,追加新 size 标签,然后 `curl -X PUT`。 - `actions/labeler@v7.0.0` `src/labeler.ts:56,111-133` + `src/api/set-labels.ts`: run 开始时快照 `preexistingLabels`,并入 config 命中项,回读一次实时标签, 再 `client.rest.issues.setLabels` —— 就是 PUT。 两者都没有把写入改成新增的输入项;`sync-labels` 也不是那个开关 —— 它只管 「config 自己拥有的标签在 glob 不再命中时是否删掉」(`labeler.ts:81-83`), 缺省已是 false。本 PR 仍把它显式写出,只为防升级漂移,不是本缺陷的修复。 整集 PUT 只在「别人的写入落在读→PUT 窗口内」时才有破坏性,所以本文件能修的是 **重叠**: 1. 两个写入方不再并发(`auto-label` needs `pr-size`)。原先由同一事件同时拉起、 窗口完全重合:PR objectstack-ai#5650 run 31051251795(`opened`)里 `Add size label` 22:03:47->22:03:49、`Label based on changed files` 22:03:47->22:03:49, labeler 的 PUT 在 22:03:49 发出 `unlabeled size/s` —— 抹掉的是它不管的标签。 2. 两个写入方不再被 `labeled`/`unlabeled` 触发。它们唯一的输入是 diff,标签事件 改不了 diff,这种 run 只能把同一个集合再 PUT 一遍 —— 零新信息,多一次互抹 机会。同 PR run 31051273625(由标签事件拉起):`Auto Label` 重算后没写, `Check PR Size` 在 22:04:22 又 PUT 了一次。两个事件类型保留在 `on:` 里, 因为 `changeset-check` 确实需要(objectstack-ai#5580)。 未被本 PR 关闭、并写进文件注释而非留给下一个读者踩:**工作流之外**的写入方 (`gh pr create` 后几秒挂标签的 agent 或人,正好落在这两个 job 运行期间) 仍可能落进 PUT 窗口被抹 —— objectstack-ai#5533 的 `skip-changeset` 豁免只活一秒就是这样丢的 (15:46:44 挂上,15:46:45 被 labeler 的 `{size/m, tests}` PUT 抹掉)。关掉这半 需要写入本身变成新增语义,不是排序问题,任何本文件的配置都替代不了。 `changeset-check` 的实时读与计数逻辑(objectstack-ai#5580/objectstack-ai#5625)、`allow-major`(objectstack-ai#5620)一字未动。 Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Aug 6, 2026
…tack-ai#5684) (objectstack-ai#5687) objectstack-ai#5650 落地的措辞是「**Add** the one label instead of writing the label set」。 意图正确,但 os-dev 手上唯一能写标签的工具(MCP `issue_write` 的 `labels`)是 整集 PUT——照字面执行 `labels: ['skip-changeset']` 恰好就是该句要禁止的整集 抹除(objectstack-ai#5683 受控实验:同秒两条 unlabeled + 一条 labeled;写并集则零 unlabeled)。 改为可执行处方:先回读当前标签集 → 写并集(现有集 + skip-changeset)→ 写后 回读确认(原有闭环保留),并记入工具面事实:`POST /issues/{n}/labels` 不可达 (容器无 gh CLI、匿名 curl 不可写),回读须走 REST `GET /pulls/{n}`, `issue_read get_labels` 解析不了 PR 号。 同句内两处把写入称作 POST 的措辞随之改为 write——同一条款内的命名一致性, 否则条款一边说唯一写法是整集 PUT、一边让读者去找一条不可达的 POST。 条款其余要素(硬步骤地位、Auto Label 不会代挂、双向竞态预期、回读进报告) 未动。 Co-authored-by: os-zhuang <hr@objectstack.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5559
背景
测试-only / 工作流-only /
.claude/-only 的 PR 不写 changeset,靠skip-changeset标签豁免 Check Changeset —— 门禁自己的失败文案就把标签列为 PREFERRED 路径。但 os-dev 的「Definition of done」收尾清单对这一步一字未提:当前 main 的.claude/agents/os-dev.md全文搜 label 零命中。于是 dev 在 PR 正文里「声明」标签而没有真正挂上,#5533、#5538 各烧一轮门禁红并由 PM 手工兜底 —— 「声明了 ≠ 执行了」正是 declared ≠ enforced 的 agent 版。改动
.claude/agents/os-dev.md收尾清单新增一条硬步骤,与「PR 正文以 Fixes 开头」同级。19 行新增、0 行删除,单文件;其余段落一字未动(含 #5630 新加的 toolchain trap 5、#5642 今日重写的 Byte discipline)。实测校正了派发词的三处认知
派发词给的新数据点是「CI Auto Label 已会自动挂 skip-changeset,文案 PR has no user-facing published change,所以硬步骤应写成回读验证为准而非无条件 POST」。逐 PR 核对 timeline 后,前半句证伪,因此条款按实测事实落笔(「回读为准」这个结论保留 —— 但理由完全不同):
os-zhuang五次、claude[bot]一次);github-actions[bot]一次都没挂过,它只挂size/*、documentation、tests、ci/cd.github/labeler.yml九条规则里没有skip-changeset;仓内唯一匹配「PR has no user-facing published change」的字符串,是本 PR 初稿里我自己写下的那一行15:46:44已落地,15:46:45被github-actions[bot]的整集写入抹掉 —— 只活了一秒,dev 侧与「没挂」无法区分整集写入会互相抹:agent 每次挂标签都伴随一条自己发出的
unlabeled,把 bot 刚挂的size/*/documentation/tests抹掉(#5533/#5538/#5642/#5645 均可见);反向就是上表第三行。本 PR 自证时更抓到纯 CI 侧的一次:22:03:48bot 挂size/s,22:03:49bot 自己把它unlabeled又挂上documentation—— 与任何 agent 动作无关。条款因此写明只加一个标签。落点在 pr-automation.yml 与写入客户端,超出本单文件面,已另开 #5649,本 PR 不修。实践自证:本 PR 自己是新条款的第一次实测
22:03:52,PR 创建后 20 秒)["documentation"]—— CI 没有代挂skip-changeset,证实上表第一、二行POST /issues/5650/labels)["documentation","skip-changeset"],documentation未被抹;timeline 里我这次写入没有产生任何unlabeled事件 —— 与六例 agent 整集写入形成对照22:04:52)["documentation","size/s","skip-changeset"]—— 三个标签齐全,size/s由 bot 自行补回预设方向被证伪的一处,如实改掉了条款措辞。 初稿按 #5542 的历史预设「首 run 必然红」,并在本 PR 正文里写过「立刻落标签让首 run 直接豁免不可达」。实测相反:标签
22:03:54落地,而openedrun(workflow run31051251795,创建于22:03:38)的 Check Changeset job 直到22:04:35才启动并做实时回读 —— 读到了早它 41 秒的标签,该 run 直接 success。所以首 run 的颜色是一场由 runner 启动耗时决定的竞态,两个方向都有实例(#5542 红、#5650 绿),第二次 commit 把措辞改成如实描述竞态,并把指导语从「预期会红」改为「尽快落标签,把首 run 的颜色当信息而不是自己的判决」。验证
- Tear down …之后一行未动。node scripts/check-nul-bytes.mjs --self-test48 assertions 绿 + 全仓扫描OK (5573 tracked text file(s));改动文件自扫grep -naP控制字节零命中。check-doc-authoring(362 files clean)、check-role-word(43 baselined, no new)绿。**四个成对、反引号 20 个成对、最大 80 列与既有条目一致。.claude/diff),Check Changeset 经标签豁免。边界
⛔ 未动
.github/workflows/pr-automation.yml(#5580/#5625 已改,#5620 在排队);⛔ 未动 pm-dispatch SKILL.md 的 PM 兜底逻辑;⛔ 未写 changeset(.claude/文档-only,走标签路线)。