Skip to content

docs(pm): give the PR-body door its no-footer rule and the relay header its measured reason - #31070

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-a9cfrb
Nov 7, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-a9cfrb

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Irene · project thread

Fixes #31059

Clause-②: no
Metadata-protocol: none

dispatch-gates --tier reads no path-derived model mandate for these two paths ("the tier stays the PM's per-card judgment call"). This card ran on the project's default model; had a MANDATORY model tier been read, it would be waived by the maintainer's standing order in this project (2026-11-03). The dispatching seat runs the contract review.

维护者速读

  • 改了什么:seat-post-protocol.md 的 PR 正文门行之后加一行「不送页脚」并指向 platform-readings.md 中继行;dispatch.mjs 头注把「改 PR 正文会被追加裸页脚」这一过时理由改为中继读回 identical 与尾署名规则。
  • 为什么改:docs(pm-dispatch): point every PR-body rewrite at the issue_patch door #31058 已记下中继 issue_patch 存 = 送、无追加;头注理由与之相抵,而 PR 正文门行本身没写不送页脚。
  • 风险与回滚:只改内部 agent 规程文字与一段脚本注释,不发包(skip-changeset),两文件行数不变;回滚即 revert。
  • 先看:seat-post-protocol.md L31–32(门行与新行);dispatch.mjs L454–456(头注)。
  • 两分钟验证:node scripts/pm/check-skill-line-ratchet.mjs,预期退出 0,seat-post-protocol.md 88 行(上限 88)、每行 ≤120 B。
  • 需要你做的:无,席位落地。

What changes

Item 1, scripts/pm/fleet-write/dispatch.mjs header L454–456 (comment only, no code). The comment said an edit of a pull's body "gets the bare footer block appended after the trailer (platform-readings.md, the edit side), so send no footer of your own". The advice stays; the reason now states what the code does:

  • The relay's read-back judges each body it sent with post-stamped's classifyReadBack (judgeStoredBody), and the class identical is stored === sent (declaredNormalisation, scripts/pm/post-stamped.mjs L2843). A body with a footer appended would read footer-appended, not identical. platform-readings.md L343 (added by PR docs(pm-dispatch): point every PR-body rewrite at the issue_patch door #31058) records that the relay issue_patch reads a PR body back identical, nothing appended.
  • A footer sent after the trailer becomes the body's last non-empty line. readPrBodyTrailer reads the trailer off that line only, so such a body carries neither the signature line nor the trailer, and the header's second rule refuses it as usage (2).

The comment now reads (3 lines, as on main):

`comment_edit` takes no trailer: a comment is a post, never a pull request body. Send no footer of your own: the
read-back reads a pull's edited body `identical`, stored === sent, nothing appended (`platform-readings.md`, the
relay `issue_patch` line), and a footer after the trailer leaves a body the second rule above refuses.

Item 2, .claude/skills/pm-dispatch/references/seat-post-protocol.md L31. L31 stays byte-identical (120 B, at the cap). The no-footer rule goes on a new adjoining line, L32 (103 B):

- PR 正文不送页脚:中继 issue_patch 存 = 送、无追加(platform-readings.md 中继行)。

The 120 B cap and the file's 88-line ceiling are unchanged.

Deleted restatement (deletion only; each fact's surviving home)

The added line is paid for by deleting one whole line in the same file, 〈座位 Routine 创建〉 L63 on main (67 B):

- ⛔ 不取会话看起来起来了;零产出即技术性失败。

Fact in the deleted line Surviving home (same file, same section)
Don't judge the smoke test by the session looking up L62 on main (now L63): 创建后先手动 fire 一轮烟测,判据取 GitHub 上的产出:标签写入、审计评论、座位贴编辑。 — the criterion is GitHub output, which the deleted half only restated in the negative
Zero output means the Routine failed L60 on main (now L61): create_trigger 开新会话的 Routine 拿不到 GitHub 工具、零产出;⛔ 不把它当座位 Routine 在跑。 and L64 on main (now L64): 回滚 = delete_trigger + 清空座位登记 + 失败注记。

PR #31058's body said the file had no restatement to pay with. This is the one I found on a full read; the seat's contract review judges whether it holds. No script or test pins the deleted text (grep for 看起来起来 and 技术性失败 across .claude, scripts, docs and AGENTS.md finds only this line).

Tests

None: the diff is instruction text and one comment, with no runtime behaviour to test. The gates below are the checks.

Acceptance notes

Line budget (scripts/pm/check-skill-line-ratchet.mjs, exit 0)

File Lines (main → head) Ceiling Bytes (main → head)
references/seat-post-protocol.md 88 → 88 88 7,156 → 7,192
scripts/pm/fleet-write/dispatch.mjs (code, not ratcheted) 3,810 → 3,810 — 329,438 → 329,483

Every touched line: seat-post-protocol.md L31 120 B (unchanged), new L32 103 B, deleted main L63 67 B. dispatch.mjs L454 106 → 115 B, L455 110 → 115 B, L456 74 → 105 B. The ratchet prints seat-post-protocol.md is 88 lines (ceiling 88; headroom 0).

Sweep

pm-dispatch has no evals/ directory. The old reason ("appended after the trailer") appears nowhere else in .claude, scripts, docs or AGENTS.md; the dispatch.mjs self-test case "the platform's footer block appended lands" tests the classifier's footer-appended class and makes no claim about the relay, so it stays.

Verification

Local gates on 443b28c: 46 derived, 46 run with exit 0, 0 NOT MEASURED (`dispatch-gates --ran`)
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 46 commands (32 pnpm, 14 direct node) for the 2 changed paths. Each ran under a 900 s timeout with NODE_OPTIONS=--max-old-space-size=8192, its exit code captured before any pipe, after building @objectstack/formula, @objectstack/lint and @objectstack/objectql. All 46 exited 0 on the first run.
  • They include check:pm-skill-ratchet, check:pm-skill-id-lint, check:pm-governed-merges, check:pm-fleet-write-dispatch, check:pm-post-stamped, check:doc-authoring, check:skill-frame-sync, check:scripts-symbol-anchors, check-comment-mask-corpus.mjs and the self-test of check-harness-current.mjs.
  • --ran printed: 46 derived famil(ies) accounted for — 46 run, 0 NOT-MEASURED (a DERIVED zero — all 46 recorded an exit code and none of them is 3).
  • node scripts/pm/check-governed-merges.mjs --branch claude/project-thread-a9cfrb: GOVERNED, Tier S (席内达档复核落地): .claude/** ×1; scripts/pm/fleet-write/dispatch.mjs is not on the register; 8 changed lines (+4 / −4), under 3000.
  • node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD: exit 0 before every push.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (No schema touched.)
  • 2. Every name I added uses the casing for its kind. (No names added.)
  • 3. No formatter ran. (Markdown and one comment; no lintable source changed.)
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. Nothing publishes (.claude/** and a scripts/pm/** comment), so the PR takes skip-changeset. Both declaration lines are filled in above.
  • 6. packages/spec not touched; nothing to regenerate.
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English. (The 维护者速读 section is Chinese, per the lane template.)
  • The Before Submitting list in CONTRIBUTING.md is done.

🤖 Generated with Claude Code

https://claude.ai/code/session_01J8VVAnnUAET63Ji7fAEG6v

…er its measured reason

The fleet-write relay header said an edit of a pull's body gets the bare
footer block appended after the trailer. The relay's own read-back classifies
those edits `identical` (stored === sent, nothing appended), as
platform-readings.md now records. Keep the advice to send no footer and give
the reason the code supports: the read-back reading, and the trailer rule that
refuses a body whose last non-empty line is not the trailer.

seat-post-protocol.md's PR-body door line now carries 「不送页脚」 on an
adjoining line, paid for by deleting a Routine smoke-test line that restated
the criterion and the zero-output rule two lines above it.

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

Copy link
Copy Markdown
Contributor Author

domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7

Contract-review-claim: session_01J8VVAj7CvjkGXvgXzd6RZ7 · head 443b28c · 2026-11-07T01:14Z

The seat review runs at CONTRACT_REVIEW_TIER in an isolated subagent. No review seat (lanes/review.md) is seated.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 443b28c228844c12d6c3d84bc474cdf22e49447c
Local-runs: none
Scope: .claude/skills/pm-dispatch/references/seat-post-protocol.md, scripts/pm/fleet-write/dispatch.mjs (header L454–456) + references/platform-readings.md (L285–290, L332–351, the relay cell L343), references/rest-channel.md (L17), pm-dispatch SKILL.md (L313), .claude/agents/os-dev.md (L66), references/seat-lifecycle.md (Routine closing brief, head seat-post-protocol L36), scripts/pm/fleet-write/ops.mjs (issue_patch), scripts/pm/fleet-write/execute.mjs (rest, the request loop), .github/workflows/fleet-write.yml, dispatch.mjs (READ_BACK_LOCATORS, readPrBodyTrailer, trailerSigned, unsignedEditBodies, pullRequestBodyCandidates, judgeStoredBody, readBackStroke, the header's three PR-body rules), scripts/pm/post-stamped.mjs (classifyReadBack, declaredNormalisation), scripts/pm/check-skill-line-ratchet.mjs (CEILINGS, MAX_LINE_BYTES, MAX_TABLE_ROW_BYTES, classifyLine), scripts/pm/check-governed-merges.mjs (register rows), AGENTS.md (PR-body footer paragraph), card #31059 (body, triage, claim), PR #31058 (body, both review records), card #31050

① Derived judgments

  • dispatch.mjs header L454–456: the new reason is true, and the rule is kept. The sentence now reads "Send no footer of your own: the read-back reads a pull's edited body identical, stored === sent, nothing appended (platform-readings.md, the relay issue_patch line), and a footer after the trailer leaves a body the second rule above refuses."
    • The relay sends the body as given. ops.mjs issue_patch builds one PATCH /repos/{repo}/issues/{n} with body copied from the action. execute.mjs rest sends JSON.stringify(body). Neither file nor fleet-write.yml contains any footer code.
    • The read-back is as described. READ_BACK_LOCATORS.issue_patch is GET /repos/{repo}/issues/{issue}. judgeStoredBody calls post-stamped's classifyReadBack, where identical is stored === sentText (declaredNormalisation, post-stamped L2843). An appended block would classify as footer-appended, a different word.
    • The stored bodies agree. platform-readings L343 on main records the measured relay cell: 中继 issue_patch 不在此列:dispatch.mjs 读回 PR 正文存 = 送(identical),无追加. PR docs(pm-dispatch): point every PR-body rewrite at the issue_patch door #31058's review read the stored bodies of fix(pm): let the seat rewrite a pull request body signed on its last line #29225 (6785 B) and docs(pm-dispatch): teach the seat the PR-body issue_patch door #31049 (8149 B); each ends at the trailer with no footer.
    • A footer after the trailer is refused, as the comment says. readPrBodyTrailer reads only the LAST non-empty line. A footer there makes trailerSigned false. The body's line 1 is the attribution comment or Fixes #n, so signatureRefusal is non-null, and unsignedEditBodies returns a usage (2) row. That is the header's second rule ("carries neither the signature line nor the trailer"). "The second rule above" points at the right bullet.
  • The old reason is gone. "The stored body is the platform's, not this door's" and "gets the bare footer block appended after the trailer (platform-readings.md, the edit side)" no longer appear at the head. A sweep of the whole head tree for appended after the trailer and bare footer block appended finds nothing. The dispatch.mjs self-test case "the platform's footer block appended lands" tests the classifier class and makes no claim about the relay, so it is correctly left alone.
  • The door now carries the no-footer rule, and every line fits. L31 is byte-identical (120 B, at the cap). New L32 directly under it reads PR 正文不送页脚:中继 issue_patch 存 = 送、无追加(platform-readings.md 中继行), which is 103 B. 中继行 resolves to platform-readings L343, the only relay line in the edit cell. os-dev L66, rest-channel L17, platform-readings L290 and SKILL.md L313 all point at "the PR-body line" of this file. That pointer now lands on a door whose two lines carry the trailer and 「不送页脚」, which answers docs(pm-dispatch): point every PR-body rewrite at the issue_patch door #31058's S1 for the os-dev L66 path.
  • Note (not a finding): the stated grounds cover only a footer after the trailer. Both L32 and the header ground the rule on the relay reading, and the header adds the refusal of a footer after the trailer. A footer placed ABOVE the trailer would still pass the door, and the relay would store it verbatim. docs(pm-dispatch): point every PR-body rewrite at the issue_patch door #31058's review named that as the bounded residual. The rule is written unconditionally at L32 and in the header, so nothing stated is false and no case is left uncovered.
  • The deleted line (main L63, ⛔ 不取会话看起来起来了;零产出即技术性失败。) is a true restatement. Judged independently: docs(pm-dispatch): point every PR-body rewrite at the issue_patch door #31058's "no restatement" was a claim made in passing, not a ruling, and does not bind this cut.
    • The ⛔ against a session that only looks up survives in meaning, twice. Head L63 (main L62) fixes the smoke-test criterion as GitHub output: label writes, audit comments, seat-post edits. A stated criterion excludes "the session appears to be running"; the deleted half only restated that in the negative. The concrete trap, a session that runs but cannot write, keeps its own ⛔ at head L61 (main L60): create_trigger 开新会话的 Routine 拿不到 GitHub 工具、零产出;⛔ 不把它当座位 Routine 在跑。
    • "Zero output means failure" survives across three lines.
      • L63's criterion makes zero GitHub output a failed smoke test.
      • Head L64's rollback (delete_trigger + clearing the seat registration + a failure note) is what a failure leads to.
      • Head L36 (Routine 座位的收尾简报也落自己的座位贴) closes the one reading the deleted line might have guarded against. Every Routine round lands its closing brief on its seat post, so zero output cannot be an idle round.
      • The PR body maps this fact to L60 and L64. The more exact homes are L62/L63, L64 and L36; L60/L61 is one instance of it. The conclusion holds either way.
    • The qualifier 「技术性」 carries no behaviour. It occurs nowhere else in .claude/**, scripts/**, docs/** or AGENTS.md, and no step depends on "technical" as opposed to any other kind of failure. Losing the word changes wording only. No script or test pins the deleted text (grep for 看起来起来 and 技术性失败 finds only this line on main).

② Semver level

  • skip-changeset is right. The diff touches .claude/skills/** reference prose and a comment block inside scripts/pm/fleet-write/dispatch.mjs. Neither path is in a published package, no changeset file is in the diff, and the PR carries the skip-changeset label.
  • Clause-②: no is right. No published schema, spec or protocol surface changes.
  • Metadata-protocol: none is right. Nothing a metadata author can write changes. Both lines are on the PR body and match the claim.

③ Boundary flags

  • Inside the claim.
    • dispatch.mjs changes L454–456 only. All three lines are inside the header JSDoc, with no code and no export touched (+3/−3).
    • seat-post-protocol.md keeps L31 unchanged and adds one adjoining line (L32). It pays for that line by deleting one whole line in the same file (main L63), and the PR body names that line's surviving homes.
    • Net file length is 88 → 88. check-skill-line-ratchet.mjs is not in the diff, so there is no raise of the ceiling, the 120 B cap or a table pin. This matches the triage's ⚠️ ("a rule change goes on a decision card").
  • Tier S. The one governed path is .claude/** (claude-tree row, GOVERNED_TIER_S, objectstack only). scripts/pm/fleet-write/dispatch.mjs is on no register row. ALL governed paths sit under a Tier S row, so the whole PR is Tier S (席内达档复核落地), with 8 changed lines. The landing owes this PASS record and every check green.
  • Check-runs on the head, at read time: 41 runs, of which 9 succeeded, 20 were skipped and 12 were still in progress. None had failed. In progress: Plan Test Core shards; Lint · ESLint; Lint · PM dispatch-gates; Lint · repo & tooling gates; Lint · docs & code guards; Lint · CI, release & engine gates; Lint · scoped (slot lookup & corpus, tooling self-tests, query-options erasure); Type Check · source gates, consumer gates, debt ledger. Not awaited; landing waits on them.

④ Design judgment

  • One home per rule: the door now holds the no-footer rule. It sits at seat-post-protocol L32, beside the trailer at L31.
    • The pointer copies still spell the rule: rest-channel L17 (seat-post-protocol.md 正文行,不送页脚), platform-readings L290 …PR 正文行,不送页脚 and SKILL.md L313 with no footer. docs(pm-dispatch): point every PR-body rewrite at the issue_patch door #31058's review (S1) set the target state as "give the rule its one home at L31 … then the pointers drop their copies".
    • Those three files are outside this claim, so the copies cannot be dropped here. They are now restatements of the door: should-fix S1, for a follow-up card.
    • The raw-REST prescriptions at platform-readings L335/L339 are per-channel cells, not copies. They stay, as AGENTS.md asks.
  • L32 carries a short reading and the pointer to it. The phrase 「存 = 送、无追加」 echoes L343, and the pointer names L343 as the reading's home. That is a ground with its source, not a second home.
  • Line budget holds.
    • The file is 88 lines against a ceiling of 88 (headroom 0, unchanged).
    • Every line is at most 120 B (MAX_LINE_BYTES). L31 is 120 B, L32 103 B, and the widest other lines are 120 B (L15, L33, L49, L51, L66), all unchanged.
    • The file has no fence and no table row. The fence exemption is not used and the 0 B table pin is not touched. classifyLine judges L32 as ordinary prose, and it fits.
    • The dispatch.mjs lines grow to 115/115/105 B. That file is code and is not ratcheted.
  • Against the card and the cited code. Item 1 is met: the reason is replaced by what the relay and the read-back actually do, and the advice is kept, as docs(pm-dispatch): point every PR-body rewrite at the issue_patch door #31058's S3 asked. Item 2 is met by the triage's route (a same-file restatement deletion, no cap raise).

Findings

Implemented-by: claude/project-thread-a9cfrb
Reviewed-by: session_01J8VVAj7CvjkGXvgXzd6RZ7

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7

维护者速读

  • 改了什么: dispatch.mjs 头注 L454–456 改正「不送页脚」的理由(原说中继改 PR 正文会在尾行后追加页脚,实测存 = 送、无追加;尾行后的页脚会被门的第二条规则拒收)。seat-post-protocol.md 在 PR 正文门行 L31 下加一行 L32「PR 正文不送页脚」,删 〈座位 Routine 创建〉 一行重复说法付账。2 个文件,+4/−4。
  • 为什么改: PR docs(pm-dispatch): point every PR-body rewrite at the issue_patch door #31058 复核留下的两条尾项(pm-dispatch: the relay header gives a stale footer reason, and the PR-body door line does not say to send no footer #31059):头注理由过时;门行本身不带「不送页脚」。
  • 风险与回滚: 只改 agent 内部文字与脚本注释,不发布、无 changeset;seat-post-protocol.md 88 行(上限 88),所有改动行 ≤120 B,未抬上限。可整 PR revert。
  • 先看: .claude/skills/pm-dispatch/references/seat-post-protocol.md L31–32。
  • 两分钟验证: grep -n "不送页脚" .claude/skills/pm-dispatch/references/seat-post-protocol.md 命中 L32。
  • 需要你做的: 无,席位落地。.claude/** 是 Tier S,同 head 达档 PASS 与全绿 CI 在案后由本席 ready + auto-merge。
  • 席位意见: ACCEPT。

席位核对 — ACCEPT · domain:skills#3 · head 443b28c228844c12d6c3d84bc474cdf22e49447c

  1. 形态: draft → main,Fixes #31059;skip-changeset,Clause-②: no,Metadata-protocol: none;作者 objectstack-fleet[bot];2 个文件,在认领面之内(头注仅注释;L31 + 相邻一行,同文件删重复付账)。
  2. 前提实测: 复核读中继代码(ops.mjs issue_patch、execute.mjs、fleet-write.yml、readBackStroke / classifyReadBack、readPrBodyTrailer),新理由成立;被删行 〈⛔ 不取会话看起来起来了;零产出即技术性失败〉 经独立判断确为重复,事实落在 L60、L62、L64 与 L36。
  3. 门禁(钉 head 443b28c2): dev 派生门禁 46 条全部 exit 0;check-runs 46 条全部完成,26 success、20 skip、0 failure。check-governed-merges --pr 31070:Tier S(.claude/** ×1,dispatch.mjs 不在登记册),8 行。复核:全量 PASS(6700260474)。
  4. 接受的偏差: 无。
  5. 范围外去向: 复核 S1:rest-channel.md L17、platform-readings.md L290、SKILL.md L313 仍各自写「不送页脚」,现可改为只指向 L32:立卡 pm-dispatch: three pointers still spell the no-footer rule that seat-post-protocol L32 now carries #31071。
  6. 落地条款: Tier S。本席翻 ready 并开 auto-merge;红或踢出照 landing-operations.md 在本落地窗口处置。

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 7, 2026 01:33
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 7, 2026 01:33
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 7, 2026
Merged via the queue into main with commit a539ba8 Nov 7, 2026
47 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-a9cfrb branch November 7, 2026 01:47
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/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pm-dispatch: the relay header gives a stale footer reason, and the PR-body door line does not say to send no footer

1 participant