Skip to content

Commit 99364ea

Browse files
fix(pm): label-write judges a release comment on post-stamped's path and no longer hangs after a comment stroke (#31640)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} --> _Requested by **Steedos** · [project thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbTjFugUJEMvp4sHgCZNYxdU)_ Fixes #31585 Clause-②: no Metadata-protocol: none ## 维护者速读 - **改了什么**:`label-write --release` 发出的释放评论,现在和其它席位评论一样先过 post-stamped 的同一个审查(`judgeBody`),没有首行署名就当场拒发;同时修好了 `--comment-file` 发评论后卡死不退出的问题。 - **为什么改**:释放评论是唯一一条不查署名就发出去的席位评论通道;而 `--comment-file` 在中继成功后进程卡死,席位重跑就把认领评论发了两遍(本卡上已发生)。 - **风险与回滚**:只动 `scripts/pm/label-write.mjs` 一个文件,不发布任何包;回滚即 revert 本 PR。没签名的释放文本从此会被拒(这是本意)。 - **先看**:`scripts/pm/label-write.mjs` 的 `composeReleaseBody`(改走 `judgeBody`)、三处 `send(packed.payload, …)`(交入 `judge`)、自测里新增的 `realTransport`。 - **两分钟验证**:`node scripts/pm/label-write.mjs --self-test`,预期最后一行 `203 cases pass across 15 batteries`。 - **需要你做的**:无,席位落地。 ## What changes 1. **`--release` judges its comment on post-stamped's path.** `composeReleaseBody` now returns `judgeBody(raw, { mode: 'comment' }, nowMs, 'label-write')` instead of `renderBody(raw, nowMs)`. The composed body (operator text, `Resume-from:` line, `{{WAS:…}}` clock provenance, all unchanged) goes through the stamp contract, the signature first line and the comment-mode keyed-line readers. An unsigned release text is exit 2, `stoppedAt: 2`, zero sends and zero writes, and the refusal is post-stamped's own text naming `label-write`. 2. **The fold hang (claim amendment, Wanted 3).** After a body-bearing relay run succeeds, `sendFleetWrite` reads the body back. With no `judge` passed, it loads one with a dynamic `import('../post-stamped.mjs')`. `label-write.mjs`, `post-stamped.mjs` and `fleet-write/dispatch.mjs` import one another, so they evaluate as one cycle, and that cycle only completes when label-write's top-level `await main(…)` does. The dynamic import waits on that same await, so it never settles. Node drains the loop and exits 13 ("unsettled top-level await") with no `④` line. This hit both `--comment-file` and `--release`. Every `send(packed.payload, …)` in label-write now passes `judge: readBackJudge()` (post-stamped's `classifyReadBack` and `sentBodyLanded`, built at call time, never at module scope). post-stamped is not affected: its entrypoint uses `main(…).then(…)`, not a top-level await. 3. **Header text** gains a `judged` step under `--release` and a section on why the read-back judge is handed in. No `.claude/**` text states the old behaviour. The one hit, `triage-duties.md` L83 (`label-write.mjs --release` 一笔中继释放), says nothing about how the comment is judged. Procedure text is unchanged. ## Tests `node scripts/pm/label-write.mjs --self-test`: 196 cases across 14 batteries before, 203 cases across 15 batteries after (head `72ff13bb`). - New battery: **the real transport** (5 cases, floor 15 batteries). It drives a claim fold and a release through fleet-write's real `sendFleetWrite`: real dispatch, real run poll, real body read-back. Only `fetch`, the clock, the sleeps and the throttle file are fake, and the fake answers from the same fake board. Each send is raced against a 15 s ceiling, so a promise that never settles shows up as `never-settled` and the event loop is not left to drain. Pins: the fold settles with exit 0 and prints `④ labels/assignees/comment ✓` and `④ MATCHES`; the release settles with exit 0 and prints `④ MATCHES — released`; and a structural pin checks that all 3 `send(packed.payload, …)` calls pass `judge: readBackJudge()`. - Release battery 32 → 34. New pin: an unsigned release text is refused before the stroke (exit 2, `stoppedAt` 2, 0 dispatches, 0 direct writes, the `label-write: REFUSED … opens with no signature line` text). New structural pin: `composeReleaseBody` returns `judgeBody(raw, { mode: 'comment' }, …)`, `runRelease` composes before `packRequest`, no `renderBody(` call is left, and label-write defines no reader of its own. The release fixture is now signed, and the signed release still sends one dispatch and reads back `④ MATCHES — released` as before. <details><summary>Reverse verification (both legs committed first, restore proven by hash)</summary> - Pin before the fix (commit `7d50fb8b`, on main's code): 4 of 200 failed. Both the fold and the release answered `never-settled` right after `run 42 completed — conclusion success`, which is the seat's live log shape, reproduced offline with no write. - Ablation of the fold's `judge: readBackJudge()` on the fixed head: 3 of 203 failed (fold settles ×2, structural send pin). Restored with `git checkout HEAD --`, hash equal to the HEAD blob. - Ablation of the judging (pass whatever renders): 2 of 203 failed (unsigned refusal, structural judge pin). Restored, hash equal. </details> ## Acceptance notes - The comment-mode readers pass a legal release body. Probed with `composeReleaseBody` on the signed fixture, and on a signed release that also quotes a line-start `Claim:` line: both `ok`. The unsigned one is refused. No reader was loosened. - `close-cards.mjs` and `issue-create.mjs` also use a top-level `await main(…)`, but they are outside the import cycle, so a lazy judge import from them should settle. Not measured live; noted only. ## Verification <details><summary>Derived gates on 5938091 (diff is one file; main merged after, no overlap with it)</summary> `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 33. All 33 exited 0, and `--ran` reconciled: 33 derived, 33 run, 0 NOT-MEASURED, 0 UNRUN. That includes `pnpm check:pm-label-write`, `pnpm check:pm-post-stamped` (761 cases), `pnpm check:pm-write-pace`, `pnpm check:refd-timer-probe`, `pnpm check:nul-bytes`, `node scripts/check-whole-set-label-write.mjs` (+ `--self-test`) and `pnpm check:pm-dispatch-gates` (fast tier, 2205 cases, 491 s). `eslint --no-inline-config scripts/pm/label-write.mjs` exit 0. After merging `origin/main` (3 commits, none touching label-write, post-stamped or dispatch), the self-test is green on `72ff13bb`. </details> --- _Generated by [Claude Code](https://claude.ai/code/session_01QsR2jR91pcCzC1k9n3p5ah)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 711c4ec commit 99364ea

1 file changed

Lines changed: 172 additions & 19 deletions

File tree

0 commit comments

Comments
 (0)