Skip to content

docs(pm-dispatch): name the hourly card refresh as a second pm:blocked returner; Blocked-by: undecorated is the spelling to write - #24345

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-24322-blocked-second-returner
Oct 18, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-24322-blocked-second-returner

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #24322
Clause-②: no

What changed

.claude/skills/pm-dispatch/SKILL.md 〈状态模型〉, the pm:blocked row: 「#N 关闭时由解锁扫描放回」 → 「#N 关闭时由解锁扫描或 scheduled-full-run-card.yml 刷新放回」. Nothing else in the row.

.claude/skills/pm-dispatch/references/state-machine.md 〈pm:blocked〉:

  • The 正典标记 line: 「、无装饰;指令是行,句中提及是散文。」 → 「、写时无装饰;读者兼收列表/粗体/反引号。」 — undecorated is the spelling to write; the reader both returners share (DIRECTIVE_PREFIX in scripts/pm/check-half-states.mjs) also accepts a list bullet and bold or backtick decoration.
  • Two new lines after 「上游已关 ⇒ … ⛔ 不反射式放行」, spelled from staleBlockVerdict's exits in scripts/ci/scheduled-full-run.mjs (held on an open, unread, closed-cross-repo or declared-Unlock-action: target; assigned; else expired):
    • 「scheduled-full-run-card.yml 经 scripts/ci/scheduled-full-run.mjs 刷新小时红卡时亦放回,规则更窄:」
    • 「双通道目标全为本仓已关卡、无 Unlock-action: 行、无 assignee 才放;跨仓已关不放。」

No behaviour change, no gate, no label, no sweep. No issue or PR number in the rule text (pnpm check:pm-skill-id-lint exit 0).

Line budget — both files stay at their ceilings

file lines before → after ceiling headroom after widest table row / longest line
.claude/skills/pm-dispatch/SKILL.md 319 → 319 319 0 pm:blocked row 296 → 336 bytes (pin 342); the file's widest row is still the 342-byte domain:engine row
.claude/skills/pm-dispatch/references/state-machine.md 41 → 41 41 0 no table row (pin 0); longest line 120 bytes (cap 120)

Two lines added in state-machine.md, both paid in the same file; every clause's survival site:

payment before after survival of each clause
① 〈pm:on-hold〉 two lines → one (−1) 「放行双查两查皆机械零判断:① 只放最近一次 pm:on-hold/pm:blocked 转换评论的条件。」 + 「② 该评论之后卡上有更新的 merged PR ⇒ 拒绝放行;⛔ 永不对更早的 blocker 放行。」 「放行双查皆机械:只放最近一次 hold/blocked 转换评论的条件;其后卡上有新 merged PR 即拒。」 (116 B) both checks stay on the new line and are also stated at SKILL.md 〈状态模型〉 「hold 放行须双查:只放最近一次转换评论的条件,其后卡上有更新的 merged PR 即拒」; 「两查皆机械零判断」 → 「皆机械」; 「⛔ 永不对更早的 blocker 放行」 is the negative restatement of 「只放最近一次…的条件」 and survives there; pm:on-hold/pm:blocked → hold/blocked, SKILL.md's own spelling (「hold/blocked 的行契约」)
② 〈pm:blocked〉 finished-work line absorbs the re-dispatch ban (−1) 「工已完、PR 被外部门禁缺陷卡住者同用本态,⛔ 不设新标签;Blocked-by: 指向那张门禁卡。」 + 「⛔ 永不给完工卡重派 dev。」 「工已完而被门禁缺陷卡住者同用本态,⛔ 不设新标签、不重派;Blocked-by: 指向门禁卡。」 (115 B) 「PR 被外部门禁卡住」 survives at SKILL.md 〈状态模型〉 「工已完、PR 被外部门禁卡住的同用本态」; 「⛔ 不设新标签」 kept; the re-dispatch ban is 「⛔ …不重派」 on the same card's line; 「那张」 dropped, its antecedent (门禁缺陷) is on the same line
within-line fold (0 lines) 〈pm:blocked〉 正典标记 tail 「;指令是行,句中提及是散文」 dropped to make room for the decoration clause 「行首」 earlier on the same line (a directive is a line) and the next line 「句中提及刻意拒收」 (an in-sentence mention is prose, refused)

No ceiling raise, no CROSS_FILE_MOVES entry, no edit to the ratchet script, no re-wrap. The seat's reading (d) was measured and only half holds: the 正典标记 tail folds losslessly (above), but the 「等发布」 half of the next line and the Part of line carry 224 bytes of distinct content (a card that closes at that moment vs. the pin-bump chore card and the Part of ban), so that fold saves no line; the second payment was taken from the on-hold pair instead.

Verification (head 9b164c9a)

Derived at base 68a090fb over the two files and re-derived with no paths at 9b164c9a (node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack): 20 commands, identical lists. All 20 run locally on 9b164c9a, each exit code captured before any pipe; --ran reconciliation: 「20 derived famil(ies) accounted for — 20 run, 0 NOT-MEASURED」.

  • pnpm check:pm-skill-ratchet exit 0 — 「SKILL.md: widest table row is 342 bytes (pin 342; headroom 0)」, 「SKILL.md is 319 lines (ceiling 319; headroom 0)」, 「state-machine.md is 41 lines (ceiling 41; headroom 0)」.
  • pnpm check:pm-skill-id-lint exit 0 — 「87 file(s) clean (pattern /#[0-9]{3,}/g)」.
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions: first run exit 3, the gate's declared prerequisite refusal (@objectstack/lint not built — nothing measured); after pnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lint under the verify lock (「VERDICT command-exit 0」), rerun exit 0 on the same tree.
  • The other 17 derived commands: exit 0.
  • Local-only pnpm check:skill-frame-freshness exit 0 (「the decision frame in this tree is current with origin/main」); its reading stays local.
  • Control-byte scan over both files: no hit. Four-axis frame untouched (pnpm check:skill-frame-sync exit 0).
  • No package touched ⇒ no build closure and no package test suite is owed; test:repo and the whole-farm lint are CI's.

Premise re-checks at 68a090fb (all hold): 解锁扫描放回 1 in SKILL.md (control pm:blocked 2); 正典标记 1 hit at state-machine.md L24 (control Unlock-action 1); export function staleBlockVerdict 1 in scheduled-full-run.mjs (control fileOrRefreshCard 8).

Acceptance notes

  • origin/main advanced to 51ad8e4f (cli/runtime) during the run; no overlap with these two files, branch left one commit behind rather than merged forward.
  • The protocol corpus names the hourly CI card nowhere, so the row names its workflow file and the reference names the workflow and the module beside the shorthand 「小时红卡」.
  • .claude/** publishes nothing: skip-changeset declared on the pr_create stroke.

维护者速读(草稿)

  • 改了什么:派发协议的两处文字。状态模型表的 pm:blocked 行多写一个放回者(小时 CI 红卡的刷新工作流 scheduled-full-run-card.yml);状态机细则里写明 Blocked-by: 标记「写时无装饰、读者兼收装饰」,并补上第二放回者的更窄规则(双通道目标全为本仓已关卡、无 Unlock-action: 行、无 assignee;跨仓已关不放)。两文件行数不变(319/319、41/41),新增两行由同文件内两处无损合并付账,每个条款的落点见上表。
  • 为什么改:刷新工作流已在 main 上这样做,协议文字却仍只写解锁扫描一个放回者,并把「无装饰」写成唯一读法;agent 按旧文字会误判卡的来路和标记的合法拼写。
  • 风险与代价(含回滚):零行为变化、零门禁、零标签、零清扫,只改 agent 读的文字;回滚 = revert 这一个 commit。代价是两处合并后的句子更紧(双查两行并一行;完工卡的「不重派」并入同卡那行)。
  • 席位意见:
  • 你要做的:无需操作。本 PR 为 Tier S,由 domain:skills 席位达档复核后入队落地。

Generated by Claude Code

…d returner

The hourly full-run card's refresh (scheduled-full-run-card.yml through
scripts/ci/scheduled-full-run.mjs) now swaps pm:blocked for pm:queue under a
narrower rule than the unlock scan. The state-model row names it beside the
unlock scan; state-machine.md carries its rule (every both-channel target a
closed local card, no Unlock-action: line, no assignee; a closed cross-repo
target never releases) and says the undecorated marker is the spelling to
write while the shared reader also accepts a bullet and bold/backtick
decoration. Both files stay at their line ceilings: the two added lines are
paid by folding the on-hold double-check pair into one line and the finished-
work re-dispatch ban into its own card's line.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1upgJbYCZ5xed9pEQF4Tz
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 18, 2026
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Oct 18, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 9b164c9a24c87d7c5ee47c81d2df7b74aa22d406
Local-runs: none
Scope: .claude/skills/pm-dispatch/SKILL.md, .claude/skills/pm-dispatch/references/state-machine.md + scripts/ci/scheduled-full-run.mjs (staleBlockVerdict, L489–L503, unchanged on main since 68a090fb), scripts/pm/check-half-states.mjs (DIRECTIVE_PREFIX, L1847), .claude/skills/pm-dispatch/SKILL.md L125 (the hold double-check sentence one fold relies on) — read on origin/main 33f700b8

Face: governed rules text (.claude/**, Tier S); rendered in seat — get_session last_served_model equals the value of CONTRACT_REVIEW_TIER. Inputs: the card (body and four comments), the PR diff read through git (origin/main...refs/pm/24322, +6/−6 over 2 files, merge-base 68a090fb), the PR body, the head's 37 check-runs. ⛔ Not the dispatch order's conclusions; the dev's report was read for its machine fields only.

① Derived judgments

  • SKILL.md L108, the pm:blocked row (335 bytes against the row cap 342; no new line; 319/319): 「#N 关闭时由解锁扫描或 scheduled-full-run-card.yml 刷新放回」 names the hourly card refresh as the second returner by its workflow file; nothing else in the row moves. Correct, id-lint safe.
  • state-machine.md L24 (120 bytes): 「…、写时无装饰;读者兼收列表/粗体/反引号。」 — undecorated is the spelling to write; the shared reader (check-half-states.mjs DIRECTIVE_PREFIX L1847: an optional list bullet and an optional run of bold or backtick markers before the directive) also accepts decorated lines. The dropped tail 「指令是行,句中提及是散文」 survives as 「行首」 in the same line and as 「句中提及刻意拒收」 on L25. Correct.
  • state-machine.md L31–L32 (116 and 109 bytes), the second returner's narrower rule: 「scheduled-full-run-card.yml 经 scripts/ci/scheduled-full-run.mjs 刷新小时红卡时亦放回,规则更窄:」 / 「双通道目标全为本仓已关卡、无 Unlock-action: 行、无 assignee 才放;跨仓已关不放。」 Read against staleBlockVerdict's exits (held on any open, unread, upstream or declared-unlock target; assigned; else expired): every target closed and local (an unread target or a closed cross-repo target is not 「本仓已关卡」), no Unlock-action: line, no assignee — all four exits covered; 「双通道」 names the body-or-comment read the patrol's reader makes. Correct.
  • Payments, two lines, both verified: 〈pm:on-hold〉 L19+L20 → one 116-byte line keeping both checks (the latest transition comment's condition only; a newer merged PR refuses); the dropped 「⛔ 永不对更早的 blocker 放行」 is the same rule stated as 「只放最近一次…转换评论的条件」, and SKILL.md L125 「hold 放行须双查:只放最近一次转换评论的条件,其后卡上有更新的 merged PR 即拒」 states both. L27 absorbs L30 (「⛔ 永不给完工卡重派 dev」 → 「不重派」 in the same 115-byte line); the dropped 「PR 被外部」 wording survives in SKILL.md L108 「工已完、PR 被外部门禁卡住的同用本态」. 41/41, longest line 120 bytes. No re-wrap: one fold, one absorption, one in-line fold.
  • No issue or PR number in any rule line; no behaviour change, no gate, no label, no sweep; no scripts/** path.
  • Accept set and public surface: none touched; Clause-②: no on the body's line 2 is right.

② Semver level

No published package is touched; skip-changeset is the correct declaration (read back on the PR's labels). No semver level applies.

③ Boundary flags

  • No open_questions. Two acceptance-note observations (the corpus named the hourly card nowhere before this PR; the doc-formula gate needs @objectstack/lint built before it measures) — outside the three filing classes, carried, not filed.
  • The second line payment came from 〈pm:on-hold〉, outside the section the claim's file surface named but inside the same file, which is what the order required — an accepted deviation, declared in the report.
  • The report's JSON sits inside a fenced block under the plain-text os-dev-report line (second time this shift); the marker scan reads it. Accepted as formatting; noted for the dev definition's wording.

Implemented-by: claude/issue-24322-blocked-second-returner
Reviewed-by: session_01V1upgJbYCZ5xed9pEQF4Tz

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)

改了什么:PM 技能两处协议文本补齐。① SKILL.md 状态表 pm:blocked 行:阻塞卡放回队列的路径从「只有解锁扫描」改为「解锁扫描,或 scheduled-full-run-card.yml 刷新」。② state-machine.md:写明小时红卡刷新这条更窄的放回规则(目标全是本仓已关卡、无 Unlock-action: 行、无 assignee 才放,跨仓已关不放);Blocked-by: 标记「写时无装饰,读者兼收列表/粗体/反引号」。两文件行数不变。

为什么改:PR #24305 已让小时红卡刷新在上述条件下把 pm:blocked 换回 pm:queue,协议文本没跟上;真实卡上的 Blocked-by: 行本就带列表与粗体、读者一直接受,文本却只写「无装饰」。devx 席按「已落地工作欠的后续照立卡」立卡,分诊定 p3。

风险与代价(含回滚):只改席位读的协议文本,不碰代码、门禁;SKILL.md 不加行(该表行 335/342 字节),state-machine.md 新增 2 行由同文件两处无损合并付账(hold 双查两行并一行,两项判据都在且 SKILL.md 另有一句;「不重派」并入完工卡那一行),席位逐条核过。回滚 = revert 本 PR。

席位意见:ACCEPT,席内达档复核 PASS(见上一条评论)。无需您裁的事。

你要做的:无需操作。Tier S,本席经中继 ready + auto-merge 入队。

席位核对

ACCEPT — PR #24345, head 9b164c9a, reviewed by session_01V1upgJbYCZ5xed9pEQF4Tz (os-steve, domain:skills#1) against GitHub and origin/main 33f700b8, not against the report.

  1. 形态: draft, base main, same-repo head; body line 1 Fixes #24322, line 2 Clause-②: no; the only closing keyword in the stored body is that Fixes; files = 2, both .claude/skills/pm-dispatch/**, +6/−6; labels skip-changeset (correct: .claude/** publishes nothing), documentation, size/s; assignee os-steve; body carries ## 维护者速读(草稿) with 席位意见 empty and ends with one session-URL footer; one commit 9b164c9a on 68a090fb with the model-free trailer pair; the branch sits a few commits behind origin/main with no overlap (mergeable true) — the queue rebuilds it onto the current main.
  2. 前提实测: the card's three re-checks re-run by the seat at 68a090fb and by the dev at its base — all hold, controls hitting (2 / 1 / 8); staleBlockVerdict and DIRECTIVE_PREFIX unchanged on main through 33f700b8; PR ci(scheduled-full-run): a refresh moves a stale pm:blocked back to pm:queue once every blocker has closed #24305 merged as 2b7fc52c3. premise_still_valid: true holds.
  3. 门禁 check-runs on 9b164c9a (read 2026-10-18T14:45Z): 38 runs — 26 success, 12 skipped, 0 in progress, 0 failed; required: success, success, skipped, success, success. Dev side: 20 derived / 20 run / 0 NOT-MEASURED at the final head, exit codes captured before any pipe (listed in the PR body); the seat re-ran no gate locally.
  4. 接受的偏差: the second line payment taken from 〈pm:on-hold〉 (same file, outside the named section — the order's rule was same-file payment); the report JSON in a fenced block under the marker line; check:doc-formula-expressions first answering exit 3 (prerequisite: @objectstack/lint unbuilt), then 0 after the closure build under the verify lock; two git pushes (probe, commit); attribution follows AGENTS.md over the harness reminder (correct).
  5. 范围外去向: two observations without a class, carrier: none — carried on this seat's post, not filed.
  6. 落地条款: Tier S (check-governed-merges.mjs --pr 24345: 2 of 2 paths under .claude/**, 12 changed lines); contract review of record PASS on this head (the previous comment); mergeable true; no generated artifact on the surface; no Restart-touch: line on any of the 14 open pm:on-hold cards. The seat readies and arms the PR through the relay (pr_ready, then automerge_enable) as soon as every check is green or an expected skip, and follows it to MERGED.

mcp_calls 0 · api_writes 2 relay strokes (pr_create with assignee and label, the report comment) · line_budget 319→319 (row 296→335 of 342) and 41→41, headroom 0 — machine fields read from the report and checked against the PR object, its labels and the branch.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants