Repository navigation
docs(skills): 补齐「跟到合并为止 / CI 诊断纪律 / 生成物同步」四类 PM 经验 (#4892) - #4893
Merged
xuyushun441-sys merged 1 commit intoAug 3, 2026
Merged
Conversation
2026-08-03 的 v17 协议变更派发里,有四类已经付出过代价的经验,现行 skill 里 没有或只写了半截。同日另一车道的 #4885 已沉淀八条,本单只补它覆盖边界之外的。 pm-dispatch —— Operational notes 由四条扩到八条: - 5:rerun_failed_jobs 复用原 run 的提交/合并 ref,不重算。红的原因若是「基上 缺一个已合并的修复」,重跑无效,只有推新提交才拿得到新的合并 ref(#4852 因此 在队列外空转 100 分钟)。与 rerun-safety-nightly.yml 无关,后者查的是测试污染。 - 6:读数纪律。cd X && cmd 短路会在错的仓里执行(跨仓一律 git -C); git grep -c | wc -l 数的是文件数不是命中数;裸名 grep 会被幸存家族当子串命中, 退役核验要带引号精确名、更硬的判据是查声明式而非提及。零命中必须用确定存在的 邻近词反查。 - 7:CI 红了先取完整日志归档。completeness check 绿只说明没有 worker 静默死掉; turbo 并发输出相邻不等于因果(test 的 dependsOn 只有 ^build,spec 无 pretest); 不要只看 tail。据错误结论开的 PR 要撤回 draft 并解绑 Fixes。 - 8:共享基础设施类修复按症状复查 main。duplicate-fix-guard.yml 只覆盖「同仓 + 同一个 Fixes #N」,#4864 与 #4856 挂在不同 issue 号下,门禁看不到,而后者先合的 60s 会被前者降回 30s。 另在 note 1 上补:「不在 main 上」是二义读数(兼容「排队中」与「没入队」);队列 分支 base sha 串成链,可读出排第几;转 draft 会同时掉 auto-merge 与队列成员资格。 step 7 之后新增「入队与落地」小节:merge=os-regen 的七条路径(含两条文档产物)、 四步同步协议、以及跟到 MERGED 而不是跟到入队为止。 spec-property-retirement: - 新增「四张 ratchet 的可见性按路线相反」—— 枚举值收窄不可见(#4391),整 def 删除必须变化(#4834:-12/-23/-5);拿错对照会双向判错。 - 修好第 2 节指向 plugin-runtime.zod.ts:243-248 的先例引用,该文件已被 #4878 整体删除。 Fixes #4892 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0176qgxgCXTJCUv4YFLtusP9
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
xuyushun441-sys
marked this pull request as ready for review
August 3, 2026 13:59
xuyushun441-sys
deleted the
claude/issue-4892-pm-skill-landing-discipline
branch
August 3, 2026 14:08
This was referenced Aug 3, 2026
This was referenced Aug 3, 2026
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Aug 4, 2026
…ing a release (objectstack-ai#4898) (objectstack-ai#4899) 17.0.0-rc.2 is versioned in main (3cfd9f0) and absent from npm. The Release run that should have published it reported success: Create Release Pull Request or Publish to npm ... 0s All changesets are empty; not creating PR changesets/action reaches its publish branch only when there are ZERO pending changesets. An EMPTY changeset still counts as pending, so a main carrying only empty ones takes neither path — no version PR, no publish, published=false, and a green run. `docker` skipped with it, so no runtime image shipped either. Two pending changesets were on main, both empty-frontmatter: objectstack-ai#4893's and objectstack-ai#4896's. Either one alone is enough. This is not an exotic state — `Check Changeset` sanctions the empty changeset as the "this PR releases nothing" declaration, so any docs/ci PR landing during the version-PR window produces it. Unstick: delete both. An empty-frontmatter changeset declares no releases, so it contributes no entry to any package's CHANGELOG — deleting it discards nothing. Its only job was to satisfy `Check Changeset` for PRs that merged hours ago. With the pending set empty, the next push to main takes the action's normal publish path, which ships the GitHub Releases and the ADR-0087 D4 spec-changes attachment along with npm and Docker. This PR therefore adds no changeset of its own — it carries the `skip-changeset` label instead. Adding an empty one would re-create the exact condition being removed and force the release down the degraded fallback path below. Prevent the silent recurrence: a recovery step after the changesets action, gated on the only fact that matters — the version in the repo is not on the registry. `changeset publish` skips versions already published, so it is a no-op on the normal path (main's version IS the last released one) and a repair on this one. It never succeeds silently: if the version is still missing after publishing, the job fails. The job's `published` / `cli-version` outputs now accept either publish path, so a rescued release still ships its Docker image instead of losing it to the same hole. The fallback cannot create GitHub Releases or the spec-changes attachment — those live inside the action's own publish path — so it says so in a warning rather than leaving the gap to be discovered later. Verified: YAML parses, both job outputs resolve on each path, the step's shell passes `bash -n`, and all three branches were exercised against stubbed npm/pnpm/git — already-published (no-op, exit 0), missing (publishes, sets published/version), and missing-after-publish (::error::, exit 1). Claude-Session: https://claude.ai/code/session_01BbNVKv6KgPzuQ5p76nMgnf Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Sep 30, 2026
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Oct 7, 2026
… — no queued PR left the queue on a draft conversion (objectstack-ai#20845) Fixes objectstack-ai#20764 Clause-②: no ## What changes `.claude/skills/pm-dispatch/references/platform-readings.md`, lines 41-43 only. The rewrite is net 0 lines, and the three new lines are 120 / 118 / 120 bytes (cap 120). | line | before | after | |:--|:--|:--| | `:41` | 转 draft 不是可靠的踢队手段:两向相反读数并存,处置按最坏走。 | 转 draft 不是可靠的踢队手段:本仓与姊妹仓均见已入队转 draft 仍保位照合,处置按最坏走。 | | `:42` | 本仓转 draft 同时掉 auto-merge 与队列成员资格,不自动恢复,转正后重挂;姊妹仓曾保位照合。 | 本仓转 draft 同秒掉 auto-merge 仅见于未入队时,转正后重挂;已入队者 2026-08-08、09-29 照合。 | | `:43` | 补救:转 draft 与卸载 auto-merge 都做 —— 本仓卸载 auto-merge 单独不踢队。 | 补救:转 draft 与卸载 auto-merge 都做,本仓卸载单独不踢队;两手齐做亦未见踢队(08-08、09-28)。 | The remedy on `:43` is unchanged: do both acts. No rule is added. The in-file citations are dates, because `pnpm check:pm-skill-id-lint` goes red on a `#`-number anywhere under `.claude/skills/pm-dispatch/`, and this file cites no PR number today. The PR numbers and timeline events are in this body. That is where the id-lint header puts a reading's provenance. ## The readings (re-readable: `GET /repos/objectstack-ai/objectstack/issues/N/timeline`) I ran a read-only timeline scan over objectstack-ai#4700-objectstack-ai#4900, objectstack-ai#6650-objectstack-ai#6850 and objectstack-ai#20400-objectstack-ai#20840. It looked for two patterns: a `convert_to_draft` between `added_to_merge_queue` and the next `removed_from_merge_queue`, and a `convert_to_draft` on a PR that was armed but not queued. The scan found every row below. The table is complete for those windows only, not for the whole repo. **Queued, then converted to draft.** None of the four left the queue because of the conversion. | PR | queued | draft | disable sent? | what followed | |:--|:--|:--|:--|:--| | objectstack-ai#6732 | 2026-08-08T14:01:50Z | 14:04:32Z | claimed in objectstack-ai#6799's text; no `auto_merge_disabled` event | the queue merged it at 14:38:56Z, 34 min later, still draft | | objectstack-ai#20420 | 2026-09-28T13:43:01Z | 14:02:28Z | claimed in the seat's 14:04Z comment; no event | its own group `pr-20420-3cf6449` had `Lint & Type Check` = failure at 14:01:49Z, before the draft; `github-merge-queue[bot]` removed it at 14:11:24Z, unmerged | | objectstack-ai#20442 | 2026-09-28T13:45:42Z | 14:02:50Z | claimed in the seat's 14:04Z comment; no event | the queue built a new group `pr-20442-b285508` for it at 14:11:29Z, 9 min after the draft; that group's `CI` = failure at 14:30:14Z; removed at 14:35:44Z, unmerged | | objectstack-ai#20695 | 2026-09-29T23:32:51Z | 23:57:02Z | no (the card discloses: draft alone) | the queue merged it at 00:04:21Z, 7 min later, still draft | **Armed, not queued, then converted to draft.** Each one dropped auto-merge. | PR | armed | draft | `auto_merge_disabled` | after | |:--|:--|:--|:--|:--| | objectstack-ai#4745 | 2026-08-03T01:28:46Z | 01:29:30Z | 01:29:30Z (same second) | ready, re-armed 01:30:52Z, queued, merged | | objectstack-ai#6727 | 2026-08-08T13:42:58Z | 13:44:36Z | 13:44:36Z (same second) | ready, re-armed 13:46:02Z | | objectstack-ai#6829 | 2026-08-08T23:37:05Z | 23:40:25Z | 23:40:26Z (1 s) | ready and enqueued 6 h later | Each disable event carries the converter as its actor. A timeline cannot tell whether the platform wrote it or a scripted follow-up did. The line records what was observed ("同秒"). ## Where the old reading came from - The "drops queue membership" reading first appears in `db6581a5` (objectstack-ai#4893, card objectstack-ai#4892, 2026-08-03). It cites no PR. That is the same day objectstack-ai#4745 dropped auto-merge on an armed PR that was not queued. The queue-membership half has no instance behind it. - `cd704cc4` (objectstack-ai#6799) later cited objectstack-ai#6732 for "only draft evicts; disable alone does not". In objectstack-ai#6732's own timeline the PR stays queued after the draft and is merged by the queue 34 minutes later. - The sister-repo half ("姊妹仓曾保位照合", objectui 2026-08-25) is carried over as it was. I did not re-read it. ## How this departs from the triage direction (5903760674) I did not choose these quietly. Each one is a place where a measurement changed what the direction assumed: 1. **`:42` is split by queue state, not "mixed" in the sense of opposite readings.** No queued PR in the scanned windows left the queue because of a draft conversion. The direction assumed the old half had its own measurement. It has none, and the one PR later cited for it reads the other way. What does go both ways in this repo is the effect by state: unqueued, auto-merge drops; queued, the PR keeps its place. 2. **`:43` says "not seen to dequeue", not "not measured".** Three PRs (objectstack-ai#6732, objectstack-ai#20420, objectstack-ai#20442) have both acts claimed in writing, and none was removed by them. The caveat: on a queued PR, the disable leaves no timeline event, so whether it was sent rests on the seats' own comments. 3. **`:41` loses "两向相反读数并存".** No opposite reading survived the re-read. ## Acceptance notes - **Out of scope, same family, Tier H.** `AGENTS.md` states the falsified reading as a premise in three places. Prime Directive objectstack-ai#14 says "draft is what removes queue membership, disabling alone drops only the arming". Multi-agent §7 says "flipping back to draft drops auto-merge and queue membership at once". The "State on your PR" paragraph says the draft flag "flipped back destroys auto-merge and queue membership at once". I did not touch them. They are reported to the seat. - **Eviction.** The only dequeue acts measured in this repo are these two. First, the queue's own ejection after a red group build (objectstack-ai#20420, objectstack-ai#20442). Second, a manual removal by a maintainer with no draft conversion (objectstack-ai#20797, `removed_from_merge_queue` 2026-09-30T07:33:36Z). Whether the remedy should name a different act is a question for the seat. It is not a rule this PR adds. - **Changeset.** `.claude/**` is not in any package's `files[]`, so this PR publishes nothing. `skip-changeset` is the seat's to apply. - **Governed surface, Tier S (`.claude/**`).** This PR stays a draft until a `## Contract review` record at `CONTRACT_REVIEW_TIER` exists for its head. ## Verification (head `02ea176a1`) - The 20 gates from `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` all exit 0. They are `check-closing-keyword-parity` (plus `--self-test`), `check-comment-mask-corpus`, `check-governed-queue-guard --self-test`, `check-harness-current --self-test`, `lint check:doc-formula-expressions` (after building `@objectstack/lint` and its dependency closure under `os-verify-lock.sh`), `check:agent-test-spelling`, `check:cross-package-test-inputs`, `check:doc-authoring`, `check:driver-memory-census`, `check:gitlink-declared`, `check:nul-bytes`, `check:pm-governed-merges`, `check:pm-half-states`, `check:pm-skill-id-lint`, `check:pm-skill-ratchet`, `check:refd-timer-probe`, `check:required-contexts`, `check:skill-frame-sync` and `check:watch-hint-literal`. - `pnpm check:pm-settings-deny-roster` was also run, because its roster lives under `.claude`. Exit 0. - `--ran` reconciliation: 20 derived, 20 run, 0 NOT-MEASURED. All 20 recorded an exit code. - `check:pm-skill-ratchet` printed: `platform-readings.md is 469 lines (ceiling 469; headroom 0)`, widest table row 0 bytes (pin 0). - Not measured locally: `check-required-contexts --verify-required-set` and `check-half-states --provenance`, which read the workflow event, and the four CI type-check lanes. This diff touches no TypeScript. ## 维护者速读(草稿) - **改了什么**:PM 协议参考文件 `platform-readings.md` 第 41-43 行,关于「已入队 PR 转 draft 能否踢出合并队列」的三条平台读数。行数不变。 - **为什么改**:旧文说本仓转 draft 会掉出队列。回查时间线后发现,本仓 4 个已入队后转 draft 的 PR 都没有因此出队。其中 2 个带着 draft 状态被队列直接合入,另外 2 个是在自身队列构建变红之后才被移出。旧说法唯一引用的实例,时间线恰好反向。转 draft 会掉 auto-merge,这一点只在「未入队」时成立。 - **风险与代价(含回滚)**:只改文档读数,不改任何规则或代码。补救仍是两手都做。风险在于读者以为有可靠的踢队手段,而实际没有。回滚就是 revert 这一个提交。 - **席位意见**: - **你要做的**:无需操作,由席位按 Tier S 复核后落地。若要让 `AGENTS.md` 里的同一旧说法一并修正(Tier H),需要你点头另开 PR。 --- _Generated by [Claude Code](https://claude.ai/code/session_01KTZmMfzVzjNvyaLyQ8mHvg)_ Co-authored-by: Claude <noreply@anthropic.com>
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 #4892
2026-08-03 的 v17 协议变更派发里,有四类已经付出过代价的经验,现行 skill 里没有或只写了半截。
本单开出来时
origin/main刚跳到e2086fef0—— PR #4885(issue #4882,另一 PM 会话),「增补 2026-08-03 运行沉淀的八条 PM 操作经验」。同一天、同一份 skill、同一类工作,挂在不同 issue 号下。这正是本单新增的第 8 条要写的那条规则的现场实例:
duplicate-fix-guard.yml只在两个 PR 声明同一个Fixes #N时开火,跨 issue 号的同类工作它看不见。所以本单先读完 #4885 全文再动笔,重叠的一律不重写:
gh-readonly-queue/*auto_merge字段入队后回落为 off)rerun_failed_jobs复用原 refspec-property-retirement1.
pm-dispatch—— Operational notes 四条 → 八条note 5:
rerun_failed_jobs复用原 run 的提交与合并 ref,不重算。note 2 讲的是「同一签名再现要重新诊断」;这条讲另一半 —— 当红的原因是基上缺一个已经合并的修复时,重跑这个动作本身就无效。#4852 的 CI 红在止血 PR #4856 落地之前,重跑仍是同一个 5000ms,直到
git merge origin/main推了新提交才拿到新的合并 ref。它因此在队列外空转 100 分钟。 判别方法:比对那个修复的合并时间与本 run 的创建时间。note 6:读数纪律 —— 三条各自产出过一个「我信了并据此行动」的错读数。
cd X && cmd短路:cd失败时整条命令继续,在当前仓里执行,产出假的「objectui 零消费方」。⛔ 跨仓一律git -C。git grep -c | wc -l数的是文件数不是命中数。system/EmailTemplate→EmailTemplateDefinition)。退役核验要带引号精确名;更硬的判据是查声明式而非提及 —— 注释 / pin 断言词 / 迁移散文里出现该名是正常且应当的。note 7:CI 红了先取完整日志归档 —— 三条读日志的纪律。
当天最贵的错误:公开断定四次 CI 红是内核 OOM-killer 杀掉 DTS 构建,据此开了 PR #4853,被 #4853 自己的 CI 推翻(挂着新参数跑,红得一模一样)。更正见 #4845。三个叠加错误各成一条:completeness check 绿 ≠ 测试通过;turbo 并发输出相邻 ≠ 因果;不要只看 tail(那次 ~10 KB 尾巴被
gen:schema的 1675 行清单吃光)。并补:据错误结论开的 PR 要撤回 draft、解绑Fixes。note 8:共享基础设施类修复按症状复查 main,不按 issue 号。
写明
duplicate-fix-guard.yml的覆盖边界(同仓 + 同一Fixes #N),以及边界外的这一例:#4864 与 #4856 修同一个基础设施问题却挂不同 issue 号,而且 #4864 若合进去会把 #4856 已合的 60s 降回 30s —— 一次静默回退。note 1 的三点补充(不重写它的主判据):「不在 main 上」是二义读数(同时兼容「排队中」和「没入队」,处置相反);队列分支 base sha 串成链,可读出排第几;转 draft 会同时掉 auto-merge 与队列成员资格。
2.
pm-dispatch—— step 7 之后新增「入队与落地」小节A. 碰生成物的 PR 入队前必须同步 + 整体重生成。 第 3 步只保证同一批内 file-disjoint,管不到先后两单都碰
packages/spec生成物 —— 而协议变更几乎必然如此。merge=os-regen会让 merge exit 0、零冲突标记却静默丢掉一侧改动,当天在 #4809 / #4846 / #4841 各复现一次。四步协议 + 一条更硬的旁证(去查上一单的实现体是否完好,条目是索引、实现体才是重灾区)。B. 跟到 MERGED 为止,不是跟到「已入队」为止 —— 维护者对此有过明确纠正。落地之后再核一次落地判据本身,因为队列的合并同样走 os-regen 驱动。
3.
spec-property-retirement新增「四张 ratchet 的可见性按路线相反」:
后果双向且都贵:前者的零变化判成异常 → 白折腾;后者的零变化判成正常 → 放过一个没真正删掉的 def。所以是先定路线再定期待读数,不能反过来。
顺手修掉一个悬空引用:第 2 节「nothing parses it」路线的先例指针写的是
packages/spec/src/kernel/plugin-runtime.zod.ts:243-248,该文件今天刚被 #4878 整体删除。改为指 #3896 / #4834(PR #4878)两个编号 + 幸存的kernel/index.ts说明块 —— 指 issue 比指行号耐放。写进去的事实,逐条实跑核过
test的dependsOn只有["^build"]turbo.json实读packages/spec无pretestpackage.json实读merge=os-regen路径清单.gitattributes实读 —— 是 7 条不是 5 条,初稿漏了docs/protocol-upgrade-guide.md与content/docs/references/**,已补,并注明权威清单是文件本身.github/workflows/ci.yml:234duplicate-fix-guard.yml覆盖边界其他
content/docs/releases/一个字未碰。.claude/skills/下两份内部 agent 说明,不含任何 workspace 包的代码或产物。🤖 Generated with Claude Code
https://claude.ai/code/session_0176qgxgCXTJCUv4YFLtusP9
Generated by Claude Code