Repository navigation
skills(pm-dispatch): 强制条款② mandates CONTRACT_REVIEW_TIER for IMPLEMENTATION of clause-② cards — drop it to TIER_DEFAULT and let the existing contract review be the gate (maintainer-authorised trial already running) #16905
Description
Activity
Claim: director seat, queue-jump dispatch on the maintainer's instruction Session: `session_01TezFG8ZMrNH6n5VTNpPpdH` Branch: `claude/issue-16905-clause2-build-tier` Worktree: `objectstack-issue-16905` Domain: `domain:skills` File surface: `.claude/skills/pm-dispatch/SKILL.md` (the 强制条款② line and the 派发 tier lines it sits among; the 轮次报告 section for the FAIL-rate counter) · `.claude/skills/pm-dispatch/references/contract-review.md` ONLY if the counter's home is there · `.claude/skills/pm-dispatch/references/lanes/skills.md` ONLY if its 常设承诺 line 「条款②闸门照现行」 must be re-pointed. ⛔ `.claude/agents/os-dev.md`, `scripts/pm/**`, `AGENTS.md`, `CLAUDE.md`, `content/docs/releases/**` untouched. (stop on breach; explain in the report) Container & model: `M`, `mode:subagent`, `model: CONTRACT_REVIEW_TIER (claude-fable-5-1)` — 强制条款① surface (the SKILL.md main file); the change cannot exempt its own landing. `Clause-②`: no (internal PM instruction surface; no published contract face). Governed surface: YES ⇒ draft PR, `needs-user-decision` on the PR + 「维护者速读」 comment, review requested from `os-zhuang` and `hotlong`; ⛔ no seat approves, merges, undrafts or arms auto-merge. Thread-read: card body only (zero comments at claim time). Serial constraints cleared: no open PR touches `pm-dispatch/SKILL.md` (searched 15:5xZ, `label:domain:skills` and the path string both return 0). Sibling queue card #16836 (`domain:skills`, `pm:queue`, unassigned) declares `references/contract-review.md` + `lanes/director.md` + `scripts/pm/check-half-states.mjs` — disjoint from this surface unless the counter lands in `contract-review.md`; if it does, this branch takes one sentence there and #16836's claimant re-merges. Local checkout fast-forwarded to `0939ba008` before dispatch.Provenance of the queue-jump. Maintainer, live PM chat with the director seat, 2026-09-08T15:5xZ, verbatim: 「插队派发 objectstack#16905 你负责派发这个卡」.
priority:p0hung as the queue-jump marker; this is a one-card exception to the director seat's no-dispatch posture, and the seat records it as such.Grading, done here because the card is bare:
domain:skills(the file is the pm-dispatch main file, owned by the skills lane per the domain table), type Task,priority:p0for the jump. ⛔ Not pre-approved: the card proposes a tier change; the maintainer's trial authorisation (recorded on objectui#5734) is the reason it jumps the queue, not a ruling on the text. The PR is the place the ruling is made, by merge.
Generated by Claude Code
- addedpriority:p0Critical: blocker, must ship before MVPCritical: blocker, must ship before MVP
on Sep 8, 2026 os-dev-report
{ "issue": 16905, "status": "done", "branch": "claude/issue-16905-clause2-build-tier", "pr": "https://github.com/objectstack-ai/objectstack/pull/16915", "premise_still_valid": true, "summary": "Narrowed 强制条款② in .claude/skills/pm-dispatch/SKILL.md (one file, 5 insertions / 5 deletions, 811 → 811 lines) so clause-② cards build at the default judgment tier and are reviewed at CONTRACT_REVIEW_TIER; 条款①, the carrier discipline, the tier fuse, lanes/spec.md criteria and the four-axis frame block (md5 22f2339f… unchanged) are untouched. Deleted as now-dead: the quota-exemption sentence for clause ② (its content is either moved to :517 or redundant with :526/:646-647/contract-review.md:60) and the enqueue gate's 「派发档位低于契约复审档」 predicate at :640, rewritten to name the actual exit 「无席内契约复审档 PASS 在案 ⛔ 禁止入队」 (matches the original 2026-08-16 gate text and the Reading B of the newly filed sibling #16912, which remains open). Counter line added in 〈轮次报告与节奏〉: 复审清单 records the contract-review FAIL rate on default-tier clause-② builds, 基线待测 (the 1/1 reading is a sample of one, not a baseline), materially above at-tier builds ⇒ revert. Governed four-piece treatment done: draft PR, needs-user-decision + skip-changeset hung and read back, 速读 comment 5588349195 posted, reviewers os-zhuang + hotlong requested (201, read back). H1-H3 hold; H4 holds for code but the script's prose/printed strings and core-rules.md:124 still describe a build-tier mandate — out of surface, filed as #16914. The assignee was already set by the dispatch; no second claim posted. PR body: the platform appended a rule line + second session-URL footer on create (prose intact, 0 angle brackets); left as-is per AGENTS.md (never re-send a body carrying an appended footer).", "tests": "All gates on commit bd26a0839 with exit captured before any pipe. pnpm check:pm-skill-ratchet EXIT=0 '✓ … SKILL.md is 811 lines (ceiling 811; headroom 0)' (first attempt EXIT=1: L514 151B / L675 167B over the 120-byte budget — compressed, not wrapped; added lines now 108/97/79/118/120 B). check:skill-frame-sync 0, check:skill-frame-freshness 0 ('current with origin/main'), check:pm-skill-id-lint 0 ('26 file(s) clean'), check:nul-bytes 0 ('scanned 8366 text file(s) … no raw ASCII control bytes'); control-char grep on the file: 0 lines. dispatch-gates --commands derived 16 families; all 16 run: closing-keyword-parity (+self-test) 0/0, comment-mask-corpus 0, governed-queue-guard --self-test 0, agent-test-spelling 0, doc-authoring 0, driver-memory-census 0, pm-governed-merges 0, pm-governed-prose 0, refd-timer-probe 0, watch-hint-literal 0; check:doc-formula-expressions first EXIT=3 PREREQUISITE NOT MET (not a measurement) → built @objectstack/formula + @objectstack/lint via os-verify-lock.sh ('VERDICT command-exit 0 · held the lock 213s · waited 0s') → rerun EXIT=0 '22 record-scoped formula example(s) across 434 files … judged clean'. dispatch-gates --ran EXIT=0 '16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED' (tree bd26a0839). pnpm lint not run (CI-owned): eslint population files ['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}'] (eslint.config.mjs:971) excludes this markdown-only diff, so 0 files affected — a population reading, not a run. No package tests affected (.claude/** only). No ablation: prose-only change, nothing built from it. Frame block md5 before/after 22f2339f0acb64cdb50c7adc9db681c3 by the dispatch's sed 734,752p recipe.", "mcp_calls": "2 — search_issues ×2 (targeted dedupe for the follow-up + control query hitting #16905); REST search was refused (repo-bound token), channel switch declared here. Everything else (issue page payload reads, PR create, labels, reviewers, comments, issue filing) went over the zero-quota payload channel or repo-scoped REST.", "open_questions": [], "out_of_scope_findings": [ "filed as #16914 (finding, Blocked-by #16905): scripts/pm/dispatch-gates.mjs CONTRACT_REVIEW_TIER docblock ('must be dispatched at'), MANDATORY_TIER_GLOBS docblock ('clause ② … is also CONTRACT_REVIEW_TIER'), the tierLines strings printed on every --tier run ('is fable-mandatory too'), and references/core-rules.md:124 「档位不足的契约卡 ⛔ 禁止入队」 still describe clause ② as a BUILD-tier mandate; out of this PR's ruled surface", "not filed (already exists): #16912, filed 16:14Z unassigned by the domain:spec seat, reports SKILL.md:640's two readings; this PR's :640 rewrite adopts its Reading B — triage may sequence or close it against PR #16915, not this dev's call" ] }
Generated by Claude Code
Contract review recorded — PR #16915 @
bd26a0839: CHANGES REQUIRED; patch round dispatched to the same seat (director seat, 2026-09-08 16:3xZ)Review: #16915 (comment) (
claude-fable-5-1, isolated seat). Ruling zone implemented exactly; one file, 811 lines, ratchet / frame-sync / id-lint green; four governed pieces present; commit trailers clean. Governed: yes — maintainer-only merge.
Reviewed-by:claude-fable-5-1isolated review seat. Implemented-by: os-dev subagent atCONTRACT_REVIEW_TIER(director seat dispatch).
Carriers: this PR carriesneeds-user-decision(governed), notneeds:contract-review; nothing to flip. Card stayspm:dispatched, assignee unchanged.Owed on the next head (same seat, same branch):
- [major] The protocol must not contradict itself. On the head,
references/contract-review.md:10, :13, :15,references/core-rules.md:113andreferences/lanes/cli.md:18still say a clause-② card is built/dispatched atCONTRACT_REVIEW_TIER. File surface widened by the director seat to those threereferences/**files (samedomain:skillsgoverned surface, same PR): rewrite the five lines in place, line-neutral (each file has its own ratchet ceiling), so every copy says "built at the default judgment tier, reviewed atCONTRACT_REVIEW_TIER".references/contract-review.mdis also declared by queue card pm-dispatch: a contract-review verdict without the label handoff is invisible to every seat — name the FAIL end-state in one sentence, and add H51 for "verdict posted on this head, carrier still on" #16836 (unassigned, no PR) — say so in the body; its future claimant re-merges. Keep pm(dispatch-gates): clause-② prose in dispatch-gates.mjs (docblocks + every--tierprintout) and core-rules.md:124 still describes a BUILD-tier mandate once the 强制条款② narrowing lands #16914 for thescripts/pm/dispatch-gates.mjsprose (out of surface) and re-scope its body to what remains. - [minor] State the :639 consequence in the body and the 速读: the rewritten enqueue gate makes an in-seat at-tier PASS the sole exit for every path-limb hit, including
Clause-②: nospec-lane PRs — stricter than skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912's current practice. Say it; do not decide skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912. - [minor] The revert half of :675 needs an actor and a comparison arm that exists after the change: the seat writing the round report records the rate; the comparison arm is the at-tier-built clause-② FAIL rate before this change (historical, frozen); revert is a decision card to the maintainer, not a seat act. Rewrite the line within 120 bytes and 811 lines.
- Re-run the gates on the new head (ratchet on every touched file, frame-sync, id-lint, nul-bytes,
dispatch-gates --ran); update the 速读 in place (edit the existing comment rather than posting a second).
After the push the director seat re-runs the tier review on the moved head; PASS ⇒ card →
pm:awaiting-maintainer, PR stays draft for the maintainer.
Generated by Claude Code
- [major] The protocol must not contradict itself. On the head,
os-dev-report
{ "issue": 16905, "status": "done", "branch": "claude/issue-16905-clause2-build-tier", "pr": "https://github.com/objectstack-ai/objectstack/pull/16915", "premise_still_valid": true, "summary": "Patch round on PR #16915 after the tier contract review (5588464964, CHANGES REQUIRED). Head e1edc4196 (origin/main 70f7d6d73 merged as merge commit b5be3f049, clean). [major] Widened surface done: contract-review.md :10/:13/:15, core-rules.md :113 (+ :124, same drift class, previously in #16914) and lanes/cli.md :18 rewritten in place so every copy says built at the default judgment tier, reviewed at CONTRACT_REVIEW_TIER; all four files line-neutral (811/60/150/29), every rewritten line ≤120 B (max 119). #16914 body re-scoped over REST to scripts/pm/dispatch-gates.mjs prose only (PATCH 200, read back), left open. [minor] :639 consequence stated in PR body and 速读: an in-seat at-tier PASS is the sole exit for every path-limb hit, including Clause-②: no spec-lane PRs — stricter than #16912's current practice; #16912 not decided. [minor] :675 rewritten (119 B): 报告席 records the default-tier clause-② FAIL rate in 复审清单, compared against the frozen pre-change at-tier historical value, exceed ⇒ decision card to the maintainer. 速读 comment 5588349195 edited in place (PATCH 200, one footer, read back). #16836's declaration of contract-review.md noted in the body. PR body PATCHed without a footer (stored body already carried the platform-appended one); read-back: prose identical prefix: True; draft=True; head=e1edc4196; appended tail bytes=59; footers=1; lt=0.", "tests": "Gates on head e1edc4196, exits captured before any pipe: check:pm-skill-ratchet 0 (SKILL.md 811/811, contract-review.md 60/60, core-rules.md 150/150, lanes/cli.md 29/29); check:skill-frame-sync 0; check:skill-frame-freshness 0 ('current with origin/main'); check:pm-skill-id-lint 0 ('26 file(s) clean'); check:nul-bytes 0 ('scanned 8369 text file(s) … no raw ASCII control bytes'); control-char grep over the 4 files: 0. dispatch-gates --commands derived 16 families (unchanged set); all 16 run on the tree that became e1edc4196: closing-keyword-parity 0/0, comment-mask-corpus 0, governed-queue-guard --self-test 0, agent-test-spelling 0, doc-authoring 0, driver-memory-census 0, pm-governed-merges 0, pm-governed-prose 0, refd-timer-probe 0, watch-hint-literal 0, doc-formula-expressions 0 after the prerequisite build under os-verify-lock.sh ('VERDICT command-exit 0 · held the lock 203s · waited 0s'); dispatch-gates --ran 0 on the committed head: '16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED' / 'derived from the tree … at commit e1edc4196'. Frame block md5 22f2339f0acb64cdb50c7adc9db681c3 unchanged. pnpm lint not run (CI-owned; markdown-only diff outside eslint's files population, eslint.config.mjs:971). No ablation (prose-only change).", "mcp_calls": "0 this round (2 for the whole run: the round-1 search_issues pair). All reads over the repo-scoped REST/comments API and payload channel; all writes (PR body PATCH, 速读 PATCH, #16914 PATCH, this report) over repo-scoped REST.", "open_questions": [], "out_of_scope_findings": [ "#16914 (finding, Blocked-by #16905) re-scoped this round to scripts/pm/dispatch-gates.mjs prose only: CONTRACT_REVIEW_TIER docblock ('must be dispatched at'), MANDATORY_TIER_GLOBS docblock ('is also CONTRACT_REVIEW_TIER'), tierLines printed strings ('is fable-mandatory too'); scripts/pm/** stays out of surface", "not filed (exists): #16912 — the :639 rewrite adopts its Reading B and is stricter than its suggested wording (PASS required for every path-limb hit, Clause-②: no included); consequence disclosed in PR body + 速读 for the maintainer; not decided by this dev" ] }
Generated by Claude Code
Contract review recorded — PR #16915 @
e1edc4196: CHANGES REQUIRED, record-only (director seat, 2026-09-08 16:5xZ)Review: #16915 (comment) (
claude-fable-5-1, isolated seat). On the text: everything owed is closed. F1 closed — all fivereferences/**lines pluscore-rules.md:124rewritten line-neutrally; residual grep over.claude/skills/pm-dispatch/**andos-dev.mdfor a clause-② build-tier mandate: 0. F3 closed (:675 names 报告席, the frozen pre-change rate, a decision card to the maintainer; 119 B). F2 half-closed: the 速读 states the :639 consequence, the PR body does not. Line counts 811/60/150/29 identical tomain; ratchet, frame-sync, id-lint exit 0; frame md5 unchanged; 「闸门只收紧不放松」 holds. Governed pieces present; RULE 2 clean. CI at 16:44Z: 0 failures, 4 jobs in progress.
Reviewed-by:claude-fable-5-1isolated review seat. Implemented-by: os-dev subagent atCONTRACT_REVIEW_TIER(director seat dispatch).Sole owed item: the PR body still describes
bd26a0839(one file, 5/5, noreferences/**rows, "#16836 not touched", no :639 consequence) while the 速读 points the maintainer at it. Sent to the same seat as a body-only rewrite — no push, head unmoved, so no third review round: the director seat reads the body back itself, then moves this card topm:awaiting-maintainer.Info for the maintainer, carried from the review: the :675 comparison arm is n=1 (say n with the rate); the 速读's "revert two commits" is three with the
mainmerge, recipe still correct.
Generated by Claude Code
os-dev-report
Body-only round: PR #16915 body refreshed for head
e1edc4196(16:49:46Z), read back — draft true, head unchanged, one footer, 0 angle brackets.{ "issue": 16905, "status": "done", "branch": "claude/issue-16905-clause2-build-tier", "pr": "https://github.com/objectstack-ai/objectstack/pull/16915", "premise_still_valid": true, "summary": "Body-only round after re-review 5588691266 (which read a body copy predating the 16:47:17Z write). PR body refreshed for head e1edc4196 via REST PATCH at 16:49:46Z with draft:true in the payload and the platform-appended footer stripped before sending: header 4 files / 11 insertions / 11 deletions / line counts 811-60-150-29; 12-row before/after table (11 rewritten lines + the deleted :522 row) with byte sizes, all six references/** rows present; 'where deleted content lives' list; :639 consequence paragraph (in-seat at-tier PASS is the sole exit for every path-limb hit, Clause-②: no included; #16912 not decided; if unintended insert 判定 yes); :675 paragraph with the new wording and the frozen comparison arm named as n = 1 (1 FAIL / 1, objectui#8583), report seat to carry n alongside the rate; #16836 disclosed as touched (3 lines of contract-review.md, its claimant re-merges); #16914 re-scoped; gates table headed e1edc4196; merge commit b5be3f049 (no trailers, no content of its own) and the two-content-commit rollback recipe named. No push, head unchanged.", "tests": "Read-back after the PATCH: prose byte-identical prefix; draft=true; head=e1edc4196; one footer (platform-appended bare form, 59 B); 0 angle brackets; no 'after (bd26a0839)' table header and no 'One file' left. check:partof-closing-keyword run locally on the STORED body with the branch's 3 commits as PR_COMMITS_FILE: EXIT=0 'carries no Part-of/closing-keyword contradiction … 3 commit message(s) carry no card-relation trailer'. No code or gate change this round.", "mcp_calls": "0 this round (2 for the whole run).", "open_questions": [], "out_of_scope_findings": [ "no new findings this round; #16914 and #16912 unchanged and open" ] }
Generated by Claude Code
Ready for the maintainer — PR #16915 @
e1edc4196(director seat, 2026-09-08 16:50Z)The sole item the re-review (5588691266) held open — the stale PR body — is closed: body read back by the director seat at 16:50Z describes head
e1edc4196(4 files, 11/11, line counts 811/60/150/29, all sixreferences/**rows, the :639 consequence, :675 with n = 1 named, #16836 overlap disclosed, gates table headed at this head),draft: true, head unchanged, one footer. No third review round: the head did not move after the text-complete verdict.State: card →
pm:awaiting-maintainer; PR stays draft withneeds-user-decision, review requested from os-zhuang and hotlong. ⛔ No seat approves, undrafts, enqueues or merges.For the maintainer (from the 速读): read the 12-row before/after table; confirm the :639 consequence is intended (an in-seat
CONTRACT_REVIEW_TIERPASS is the sole enqueue exit for every diff touchingpackages/spec/src/**,Clause-②: noincluded; if not, 「判定yes」 goes in before the PASS clause — one more patch round); agree ⇒ approve + merge by hand; disagree ⇒ close the PR, the text has no side effects. #16912 and #16914 stay open for triage.
Generated by Claude Code
裁决记录 —— 选项 A 采纳:clause-② 卡默认判断档施工、契约复审档复核。2026-09-09,维护者回批逐字「同意」
呈报为总监席格式决裁批第 1 批第 ③ 项(本会话)。选项 B(维持现状)与 C(限期试点)被否 —— A 作为永久规则采纳,而非试点。
SKILL.md:675的 FAIL 率计数器(报告席记入复审清单,超改制前达档史值 ⇒ 立决策卡交维护者定回退)仍按 PR #16915 现有措辞保留,它是常设仪表,不是试用期条款。状态:不变,仍
pm:awaiting-maintainer—— 这一张是正确分类剩下的唯一动作是合并受管面 PR #16915,而
.claude/skills/**的四件套明令 ⛔ 无席位批准或合并。⇒ 本卡属该状态的定义面(决定已做,只剩一次席位做不到的人工动作),⛔ 不转决策箱。⚠️ 尚未裁的一项 —— ⛔ 不要让它随 A 默认落地呈报时单独要过一个 y/n,本次回批未答,故记为悬置:
PR #16915 重写后的
SKILL.md:639把「席内契约复审档 PASS 在案」变成每一条路径肢命中的唯一出口 —— 包括Clause-②: no的 spec 车道 PR、包括已在达档施工的 PR。这比 #16912 记录的现行做法更严(#16899 / #16901 是在check-clause2-carriers --pairexit 0、无 PASS 的情况下入队的),也比 #16912 自己建议的措辞更严。- y = 就要这个更严的口径,
:639按 PR 现状落地。 - n = 需在
:639的 PASS 从句前插入「判定yes」,把它收回到只管 clause-② 判定为 yes 的卡。
⇒ ⛔ 合并 PR #16915 之前请先答这一项。#16912 仍 open,本 PR 不决定它。
另一项请维护者先看一眼的读数(⛔ 本席不动)
PR #16915 正文自称「stays draft … no seat approves, undrafts, queues or arms auto-merge」,而 API 现读
draft: false;requested_reviewers只有hotlong一个,而正文声称向两个授权账户请审。两种读法:维护者已亲自 undraft,或受管面纪律在某一步被破。⛔ 本席不据此下结论,也不改 PR 状态。出口
合并后由达档总监席核验
SKILL.md:514已改、pnpm check:pm-skill-ratchet绿,再以合并 commit 为证据摘pm:awaiting-maintainer。
Generated by Claude Code
- y = 就要这个更严的口径,
出口核验:PR #16915 已 MERGED,本卡已关闭 —— 但
:639的 y/n 在合并前未被回答,更严的那一版已落地- 关闭:2026-09-09T02:17:49Z,
completed,byos-zhuang;PR skills(pm-dispatch): clause-② cards build at the default tier and are gated by the contract review at CONTRACT_REVIEW_TIER (#16905) #16915 MERGED。 - 本笔同时摘掉残留的
pm:awaiting-maintainer(SKILL.md:133:关闭即在同一笔摘掉pm:*状态标 —— 该标在关闭时未摘,属 H22 残留)。priority:p0、domain:skills留下。
落地实测(
origin/main,本会话重新 fetch 后直读):514 强制条款②:凡放宽接受集或扩大公开面的卡默认判断档施工、契约复审档复核。 :517 条款②只指已发布契约面,拉回已声明契约不触它;卡面复述仍是条款②。 :639 `--tier` 嫌疑行是提示非裁定;双肢命中任一 ⇒ 无席内契约复审档 PASS 在案 ⛔ 禁止入队。行数 811,压在 shrink-only 天花板上 ⇒ ratchet 未被突破。⇒ 裁决 A 的正文部分完整落地,符合维护者「同意」。
⚠️ 但:639落的是未经裁决的严格版呈报时本席单独要过一个 y/n,并明写「⛔ 合并 PR #16915 之前请先答」。回批只答了 A,未答该项;PR 在此后约十分钟合并。⇒ 现在 main 上的规则是:
双肢命中任一 ⇒ 无席内契约复审档 PASS 在案 ⛔ 禁止入队。
⛔ 没有
判定 yes限定。后果:任何 diff 触及packages/spec/src/**(路径肢)的 PR,包括Clause-②: no的 spec 车道 PR、包括本身已在达档施工的 PR,在没有席内CONTRACT_REVIEW_TIERPASS 在案之前一律不得入队。这严于 #16912 记录的现行做法(#16899 / #16901 是在check-clause2-carriers --pairexit 0、无 PASS 的情况下入队的),也严于 #16912 自己建议的措辞。⇒ 这不是缺陷,是一条未被明确裁决就生效的收紧。 两条出路,⛔ 本席不代选:
- 保留:确认这就是要的口径,skills(pm-dispatch): the clause-② enqueue gate at SKILL.md:640 has two incompatible readings — one of them freezes the whole domain:spec lane whenever fable is out, and makes check-clause2-carriers --pair exit 0 unreachable #16912 据此收敛,spec 车道从此每张 PR 都先跑席内契约复核。
- 收窄:一次单行 PR,在
:639的 PASS 从句前插入「判定yes」,把它限回 clause-② 判定为 yes 的卡。⚠️ 受管面 ⇒ 仍走四件套人工合并;且SKILL.md行数已零余量,插入须由删除支付。
#16912 仍 open,它是这条的自然落点。
Generated by Claude Code
- 关闭:2026-09-09T02:17:49Z,
- added a commit that references this issue
on Sep 9, 2026
Filed by the
domain:spec@ objectui seat (session_01Jmxdo7bmeqCQHLSfmLVX9w,os-warren) on the maintainer's direct instruction. ⛔ Filed unassigned, not claiming —.claude/skills/pm-dispatch/SKILL.mdis thedomain:skillslane's governed surface and this seat ⛔ neither owns it nor edits it.⛔ Routing input only, ⛔ not a lane assignment: this plainly lands in
.claude/skills/pm-dispatch/SKILL.md, which the domain table puts indomain:skills. Grading anddomain:*are the triage seat's.The maintainer instruction
Asked whether a fable review makes a fable build unnecessary, then, verbatim: 「开skill卡,在裁决落地之前,你直接按新规则试行。」
⇒ Two things, and they are separable: (1) this card, to change the text properly through a governed PR; (2) a trial already in force in the⚠️ The trial is the maintainer's authorisation, ⛔ not this card being pre-approved, and ⛔ not a licence for any other seat to deviate from the text as written.
domain:spec@ objectui lane, recorded on that seat post.What the text says today
SKILL.md, 〈派发〉:⇒ A clause-② card is built and reviewed at
CONTRACT_REVIEW_TIER. The proposal is to keep the review there and drop the build toTIER_DEFAULT.⭐ Why this is a narrowing of an inconsistency, not a new idea
① The architecture already declares review to be the compensation for low-tier dispatch.
references/contract-review.md, 降档保险丝:That sentence only makes sense if low-tier dispatch + high-tier review is an anticipated, sanctioned shape. 强制条款② is the one place that shape is forbidden.
② The same trade is already ruled, by the maintainer, for another surface class.
scripts/pm/dispatch-gates.mjs, recording the 2026-08-20 ruling verbatim 「接受你的建议 — fable 当审计师用,不当施工队用」:And
SKILL.mdalready carries the mechanism with a name — 「降档施工的补偿控制 = 复核席跑契约复审档」 — scoped to references-only and one-line mechanical governed edits. ⇒ This card asks whether that scope should include clause ②.③ The cost asymmetry is measured, not assumed. From this seat's round R1, two devs on comparable-sized cards:
claude-fable-5-1opus⇒ Tier barely moves token COUNT (1.6% apart). It moves unit price. The contract review that gated the first of those cost 211,330 tokens — so build is the large line item and review is the small one, and 强制条款② puts the expensive tier on the large one.
The fable-built PR in that very round FAILED its contract review (objectui#8583 / PR #8601, verdict at objectui#8583 comment
5587871554). The build graded a public-surface widening as apatchchangeset; it should beminor. The reviewer found it by checking the build's cited precedent against four counter-precedents.That cuts both ways and an honest card has to say so:
Clause-②: no, a census/classification task of a different shape from the fable card's declaration widening. Two cards, two task shapes, ⇒ proves nothing about tier and quality. ⛔ Do not carry "the opus dev did the better work" forward as evidence; it is true of that round and does not generalise.Proposed change
In
SKILL.md, 强制条款② — the accept-set/public-surface half moves from build-tier mandate to review-tier mandate:TIER_DEFAULT;CONTRACT_REVIEW_TIER, unchanged, and the carrier discipline (needs:contract-reviewon card and PR, cleared only by a posted verdict whose ownScope-covered:line covers the whole change) is unchanged;SKILL.md, the decision-frame copy,.claude/agents/os-dev.md) is untouched — that is a different mandate with a different rationale, and ⛔ this card does not widen into it;CONTRACT_REVIEW_TIER⛔ still never clears a carrier itself.check-skill-line-ratchet.mjs: this file's line count only ever goes down. ⇒ the edit must pay for itself by deletion, and ⛔ re-wrapping does not count as paying. Plausibly this is net-negative anyway — it collapses a special case into the general 降档施工/补偿控制 rule that already exists.The tripwire this needs, and why it is the load-bearing half
⛔ Do not land this as a permanent rule with no instrument. Adopt it with a measurement:
Executable acceptance criterion
SKILL.mdstates that a clause-② card is built atTIER_DEFAULTand reviewed atCONTRACT_REVIEW_TIER;pnpm check:pm-skill-ratchetpasses (line count not increased);check:skill-frame-sync/-freshnesspass; and the round-report section that carries contract-review outcomes names the FAIL-rate counter.Governed-surface note
.claude/skills/**is a governed surface ⇒ terminal four-piece treatment: ⛔ no seat approves or merges it, the PR getsneeds-user-decisionplus a 「维护者速读」 comment, and review is requested from both authorised accounts.SKILL.mdis itself a 强制条款① surface, so the PR that changes it is built atCONTRACT_REVIEW_TIERregardless of what it says about clause ② — the change ⛔ cannot exempt its own landing.Refs: the 2026-08-20 ruling recorded in
scripts/pm/dispatch-gates.mjs(MANDATORY_TIER_GLOBSdocblock) ·references/contract-review.md降档保险丝 · objectstack-ai/objectui#8583 and its verdict5587871554(the measured FAIL) · objectstack-ai/objectui#8327 (the opus-built card) · objectstack-ai/objectui#5734 (the seat post carrying the trial)