docs(agents): the contract-review carrier is the seat's to hang; --pair PR-NUMBER is the only spelling - #18250
Conversation
…air PR-NUMBER` is the only spelling os-dev.md: the dev never hangs, removes or waits for `needs:contract-review`; it reports the carrier state seen on the PR and the `--pair PR-NUMBER` exit code as a reading. A refused additive label write is reported with endpoint and status for the seat to hang — never `blocked`, never MCP. SKILL.md: the one `--pair N` token becomes `--pair PR-NUMBER`. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr
…rrier-is-the-seats-to-hang
…e PR creator SKILL.md :645 now says the seat hangs `needs:contract-review` in the same stroke: on the PR as soon as it exists, on the card first when the report arrives before the PR — the order contract-review.md already states. Equal-line, paid by density. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr
…rrier-is-the-seats-to-hang
Contract reviewServed-tier: Reviewing seat: ① Derived judgments
② Semver levelNot applicable — nothing published moves; ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
维护者速读(终稿)改了什么:两份席位规则文件各改两行,等行数、每行 ≤ 120 字节。① 为什么改:原文要求 dev「开 PR 同笔挂标签」,而 objectui 的两名 dev 实测被容器的写分类器拒绝——照做的 dev 失败、报告失败的 dev 看起来像抗命;同一行还把 风险与代价(含回滚):纯文本、不碰发布包、不改 CI;行数不变。回滚 = revert 一个 PR。放宽容器写权限(方案 B)是权限面的事,不在本 PR,由你另定。一处已知残留: 席位意见:建议批准。本席在 head 上亲核:四行内容与字节(119/114/101/118)、棘轮 403/403 与 812/812、frame 块 md5 不变、id-lint 与 frame-sync 绿、 你要做的(一个动作):approve 本 PR。approve 后本席翻 ready + 入队。 Generated by Claude Code |
|
Ruling-C landing provenance — skills seat, session Generated by Claude Code |
Fixes #18181
What changed
Three lines across two governed rules-layer files; line counts unchanged (os-dev.md 403/403, SKILL.md 812/812), every edited line at or under the 120-byte cap, no re-wrap anywhere, and the decision-frame block SKILL.md :734–:755 untouched (md5
3327d02c56f8a0eca88569dad2270f32before and after)..claude/agents/os-dev.md:287 — the line the card names, re-derived onb3b43b6(the card body's:288had drifted; the filer's correction comment 5664488072 gives :287):The dev no longer hangs the carrier. It never hangs, removes or waits for
needs:contract-review; it reports whether the label is present on the PR and the--pair PR-NUMBERexit code — as a reading, not as a gate it must clear..claude/agents/os-dev.md:301 — the neighbouringskip-changesetlabel-write rule (mechanism assumption A2, same file surface, same class — an additive label write the container may refuse):One rule now covers both carriers: a refused additive label write is reported with endpoint and status and the seat hangs the label; the dev never reports
blockedfor it and never switches to an MCP write..claude/skills/pm-dispatch/SKILL.md:646 — the one--pair Ntoken (REGION claim: this line only):--pair PR-NUMBERis now the only spelling in the three governed files (contract-review.md :42 already spelled it so).Why
Direction A of the card's grading (comment 5673619664), executed as ruled: the
needs:contract-reviewcarrier is the PM seat's to hang — on the card at the claim and on the PR when the PR appears — which is what every seat already does; the dev never blocks on a label write;--pair PR-NUMBERbecomes the only spelling. Option B (granting the dev container the label write) is a permissions widening and was ruled not this card.The two defects the card and its correction measured: a dev that obeyed :287 literally was refused the additive label write by its container's write classifier on two independent objectui runs, while an objectstack dev could write it — per container, unknowable in advance; and
--pair NboundNto the nearest referent, the card, while the script takes a PR number and answers a card number with exit 2 (UNJUDGED), which a naive capture reads as a red gate.Mechanism readings
b3b43b6(108 B; the card's :288 is theskills/**line). Replaced as above. Under the byte cap theClause-②: yestrigger did not fit, so the rule is now unconditional: on every PR the dev hangs nothing, removes nothing, waits for nothing, and reports carrier presence plus the--pair PR-NUMBERexit code. That superset is deliberate —--pairalso carries the widening-tell row, which only fires on aClause-②: noclaim, so a reading on every PR is worth more than one onyesclaims alone.被拒 ⇒ 停下报 blockedis the same container-refusal class one line over, and nothing aboutskip-changesetrequires the dev to block on it: CI's changeset gate reads the label, the dev's report says whether it landed, and the seat can hang it on that report. So one rule covers both carriers and :301 changed as above; :299 (the label is your step, hang it as soon as the PR opens) and :300 (additive endpoint) stay — the dev still attempts the write. The live half of the measurement is this PR's ownskip-changesetwrite; its outcome (landed, or the endpoint and status of the refusal) is in theos-dev-reportcomment on the card, not here, because the PR body is written before the label write and is not re-sent.git grep -n -- '--pair N\b' -- '.claude/**' 'scripts/pm/**': before 6 hits (os-dev.md :287, SKILL.md :646, and 4 inscripts/pm/**); after 4 hits, all outside the claimed surface:check-clause2-carriers.mjs:24 and :490 (docblocks), :4947 (a self-test title), andcheck-widening-tells.mjs:492 (docblock). In the three governed files the count is 0. Lit control--pair PR-NUMBER: 1 before (contract-review.md :42), 3 after (:42, os-dev.md :287, SKILL.md :646). The script docblocks bindNto a PR number in their own text (:11 spells--pair 13910 # ONE PR), so the ambiguity is not live there; noted below, not edited.cd /home/user/objectui && PM_SWEEP_REPO=objectstack-ai/objectui node ../objectstack/scripts/pm/check-clause2-carriers.mjs --pair 9552exits 0 with the provenance lineevery row below is read from objectstack-ai/objectui (source: PM_SWEEP_REPO)and the verdictPR #9552 / card #6910 — the clause-② declaration is readable in the fixed spelling and both carriers agree(token present, 3 reads served; the proxy re-exec happened by itself). A control on objectui#9495 (no longer open) exits 2 — UNJUDGED, with the board still retargeted. So the invocation works from a sibling checkout. The byte cap leaves no room on :287 for the invocation (the line stands at 119 B), so the line carries only the flag spelling; the script header (:20–:24) already spells the sibling invocation and every run prints the board it read, which is the remedy text the ruling asks to keep in the script.Gates
Derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no paths; change set from the merge base): 18 families ona2cbbef0, re-derived on the merged head0c934967(merge base68fea8bc) — identical list. All 18 run in the foreground on0c934967, exit codes captured by redirect before any pipe, all 0:check-closing-keyword-parity(+--self-test) ·check-comment-mask-corpus·check-governed-queue-guard --self-test·check:doc-formula-expressions(lint pkg) ·check:agent-model-declared·check:agent-test-spelling·check:commit-card-trailers·check:doc-authoring·check:driver-memory-census·check:nul-bytes·check:pm-governed-merges·check:pm-governed-prose·check:pm-skill-id-lint·check:pm-skill-ratchet·check:refd-timer-probe·check:skill-frame-sync·check:watch-hint-literalReconciliation on
0c934967:✓ dispatch-gates --ran: 18 derived famil(ies) accounted for — 18 run, 0 NOT-MEASURED (a DERIVED zero — all 18 recorded an exit code and none of them is 3).Verdict lines:
✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 403 lines (ceiling 403; headroom 0)·✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 812 lines (ceiling 812; headroom 0)·✓ check-agent-model-declared: 1 agent definition(s) under .claude/agents/ all declare a model·✓ check-skill-id-lint: 27 file(s) clean·✓ check-skill-frame-sync: the one declared copy of the decision frame is internally coherent.check:doc-formula-expressionsfirst answered exit 3 (PREREQUISITE NOT MET —@objectstack/formulaand@objectstack/lintunbuilt in a fresh worktree); prerequisite built under the verify lock (turbo run build --filter=@objectstack/formula --filter=@objectstack/lint, VERDICT command-exit 0), rebuilt again after the merge, then the gate exits 0. The exit 3 is not a measurement and is not counted as one.Not run locally, by design: the 11 wide-population families and the whole-repo
pnpm lintsweep belong to CI. Control-byte self-scan on both edited files: no hits.Line budget
.claude/agents/os-dev.md.claude/skills/pm-dispatch/SKILL.mdPaid by density in place; no line merged or split.
Deviations, declared
N→PR-NUMBER, +8 B) puts the line at 124 B, over the 120-byte cap. Two characters were dropped on the same line (在,即), content unchanged, landing at 118 B. Still inside the one-line REGION claim.Clause-②: yestrigger is gone for the byte cap; the rule is unconditional (see A1). If the seat wants the trigger back, the price is the作读数tail or the不等limb.skip-changeset: nothing published moves —.claude/**is on the fast path (no packagefiles[]ships it).origin/mainmerged at68fea8bc(one spec commit, nothing on this surface) before opening; pm-dispatch: reconcile the quota rows with the identity-bound rate limit; merged-write rule; account-suspension recovery readings #18242 remains open on SKILL.md :172–:185 — disjoint from :646.Acceptance notes
needs:contract-review,PR 创建者,同笔挂, SKILL.md, direction A): SKILL.md :645 still reads 「needs:contract-review(恒英文)由 PR 创建者随可复审契约增量同笔挂:draft PR,或先到的报告。」 For a dev-created PR the creator is the dev, which direction A says never hangs it. Outside this card's REGION claim (:646 only), so not edited here; it sits on the SKILL.md chain the seat owns.--pair Nspellings remain inscripts/pm/**docblocks and one self-test title (listed under A3); each is next to text that binds N to a PR number. 承接者:无.os-dev-reportcomment with a read-back; under one shared identity the author field says nothing about who hung what.维护者速读(草稿)
改了什么:改了两个受管规则文件里的三行,行数不变。开发 agent 定义(os-dev.md)一行:
needs:contract-review这个标签归席位挂,开发 agent 不挂、不摘、不等,只在报告里写 PR 上有没有它、以及--pair PR-NUMBER的退出码,作读数。另一行:加法写标签被容器拒绝时,报端点与状态码、由席位代挂,不再报blocked、不走 MCP。PM 技能(SKILL.md)一个 token:--pair N改成--pair PR-NUMBER。为什么改:两次独立实测里,开发 agent 的容器拒绝写标签,而规则要求它开 PR 同笔挂——照做就失败、如实报告又像抗命。分诊裁定 A 向:载体由席位挂(认领时挂卡、PR 出现时挂 PR),开发 agent 只报所见。同一行的
N让人绑到卡号,脚本要的是 PR 号,给卡号返回 exit 2(未判),会被当红灯读;PR-NUMBER是唯一拼写。风险与代价(含回滚):行数与上限不变,每行 ≤120 字节,决策框架块未动。风险是开发 agent 不再自己挂载体,若席位漏挂,条款② PR 的载体会缺失——但席位侧已经是现行做法,且开发 agent 报告的
--pair读数会暴露缺失。回滚 = revert 本 PR,无其他副作用。席位意见:
你要做的:审阅上面三行措辞(尤其 :287 去掉了
Clause-②: yes触发词、改为对每个 PR 都成立);同意即给授权批准,由席位落地;不同意请指出要保留的措辞。Generated by Claude Code