Skip to content

docs(pm-skill): judge responsibility before dispatch, breaker on reopening security review - #21999

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-21929-judge-responsibility-before-dispatch
Oct 6, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-21929-judge-responsibility-before-dispatch

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #21929
Clause-②: no

What changes

Five files under .claude/skills/pm-dispatch/, eight lines added or rewritten, eight lines deleted, every file at its ratchet ceiling before and after. The card's four rules land where the seat claims, dispatches, grades and reviews; the dispatch prompt's ruling section is bound through the claim template; the round report gains a per-PR breaker line. No gate, workflow, hook or ratchet is added or moved, as the triage grade asked. .claude/agents/os-dev.md, skills/**, scripts/** and .github/** are untouched.

Rule File : line (after) Action Line (bytes)
1 · responsibility check, the three questions SKILL.md 〈模板与表〉 claim template, under Clause-② new template field Responsibility: — whose code produces the risk / the platform path that already covers it, or none / who reaches it and whether anyone uses it today; n/a — not a defect card otherwise; the parenthetical binds the dispatch prompt's ruling section to repeat the three answers fence (exempt)
1 · the document-not-defend verdict SKILL.md 〈升级与决策〉 :214 new escalation condition: 或责任三答齐指他人代码、已有正路、仅最高权限可达 ⇒ 只提文档或决策卡,⛔ 不派码。 120
1 · asked at first grade (triage) references/triage-duties.md :74 rewritten: 首触答责任三问:谁的代码出险/有正路否/谁可达且有人用否;据答改卡范围、域与路由。 117
2 · no security boundary on a heuristic SKILL.md 〈升级与决策〉 :215 new escalation condition: 或修复以猜测(键名、值形状、模式表)定安全边界 ⇒ 决策卡先比对声明式方案。 108
3 · circuit breaker, consequence references/execution-duties.md 〈复核〉 :182 rewritten ESCALATE verdict: 判决 ESCALATE:见〈升级与决策〉;熔断任一命中亦判,PR 暂停,答复前 ⛔ 不派下一轮。 110
3 · circuit breaker, the three conditions references/execution-duties.md 〈复核〉 :183 new: 熔断三条:独立安全复审连续 2 轮不过;diff 超首次复核规模 2 倍;上轮修复引入新 HIGH。 114
3 · round report records the hit references/seat-lifecycle.md 〈轮次报告与节奏〉 :68 rewritten: 报告加升级项、代裁清单(分诊)、awaiting a human merge 项、逐 PR 熔断命中项(无则 none)。 113
4 · price by reach, not by class references/filing-gate.md 〈定级判据〉 :43 new, directly under 「沿链继承只给上界」: 可达面定上界:\security` 标签不抬级;仅最高权限可达且无现用者至多 p3,可记录不修。` 112

Reading the escalation enumeration after the edit (SKILL.md 213–216): 只在至少一条成立时升级 → the existing disagreement condition → rule 1's verdict → rule 2's condition → the existing destructive/hard-to-roll-back condition with its 「其余归 PM 裁量」 closer. The decision-frame block (**每个方案必须沿四条固定评估轴分析 … 交维护者拍板。) is byte-identical; its md5 is abff5f852c8fd09b79ec0623439aa4f0 before and after.

Why these spellings:

  • Rule 1's verdict sits in 〈升级与决策〉 rather than in execution-duties.md, because both the triage seat and the execution seats read SKILL.md, and the verdict is a "do not dispatch code" decision — the same class as the enumeration it joins. ESCALATE already means a decision card with options and a recommendation in the maintainer's inbox, and a needs-user-decision card is never dispatched (红线), so "asks the maintainer with a short summary and options" and "no further round until the maintainer answers" ride on existing machinery; the ESCALATE line still says PR 暂停,答复前 ⛔ 不派下一轮 so the seat does not have to infer it.
  • "at most low" is spelled 至多 p3: p3 is this repo's lowest grade and the grade triage-duties.md already assigns to a reach:-less finding that is recorded without a dedicated fix. 可记录不修 is the "may be recorded without a fix" half.
  • 他人代码 stands for third-party or user-authored code (the first answer is "someone else's code produces the risk"); the long spelling did not fit in 120 bytes beside the other two answers.

Line budget (headroom 0 on every file, net 0 on every file)

File Before After Ceiling
.claude/skills/pm-dispatch/SKILL.md 319 319 319
references/execution-duties.md 183 183 183
references/dispatch-runbook.md (not edited) 241 241 241
references/seat-lifecycle.md 96 96 96
references/triage-duties.md 120 120 120
references/filing-gate.md 58 58 58

The dispatch budget was at most 8 added or rewritten lines across all files: 8 were spent (5 new, 3 rewritten in place). Every new or rewritten prose line is at or under 120 bytes (LC_ALL=C awk; the figures are in the table above); the one template field is inside a fence, which the rule exempts. No line was re-wrapped; each added line is paid by deleting a line whose rule survives elsewhere, listed here with its surviving home:

  1. Deleted SKILL.md 〈报告契约〉: - \reach:` 无实测 ⇒ ⛔ 不立卡,例外三种与定义见立卡门 ①;同轮报告互读,同族只开一张。Survives inreferences/filing-gate.md立卡门 ① (lines 12–14: thereach:definition and the three exceptions; line 20:⛔ 不是卡:三类外或无 `reach:` 的 `finding`), in references/triage-duties.md47–48, and in the kept SKILL.md line同族发现并入收口卡(一卡覆盖全族位置,带枚举钉子),⛔ 不开单点卡;无则第二次即开。`; the kept line 「席位读 PR … 经立卡门补立」 still points at 立卡门.
  2. Deleted SKILL.md 〈机械守卫索引〉 row for scripts/pm/git-history.mjs.
    Survives verbatim in AGENTS.md (Multi-agent working discipline: "A windowed history question … goes through scripts/pm/git-history.mjs — answer, or REFUSE … historyHorizon() is the read-only predicate"), and the tool's use is still named in references/seat-lifecycle.md 19.
  3. Deleted SKILL.md 〈机械守卫索引〉 row for the guard-main-checkout / guard-shared-stash hooks.
    Survives in AGENTS.md Prime Directive 11 and Multi-agent working discipline (both hooks, their escape variables and the stash replacements), and the rule itself in SKILL.md 红线 ⛔ 永不编辑共享检出,一任务一 worktree;⛔ 永不 \git stash`。`.
  4. Deleted references/execution-duties.md 〈认领〉: - \Clause-②: yes` 至少 `minor`:AGENTS.md Post-Task Checklist 第 3 条,本行在认领处复述。A self-declared restatement; survives inAGENTS.md Post-Task Checklist step 3 (yestakes at leastminor), which binds every seat, and is enforced on the PR by the changeset gate that reads the body's Clause-②` line.
  5. Deleted references/filing-gate.md 立卡门: - 判例:自注「未测量」的 (b) 卡 ⇒ 不立;\reach:` 记公开入口一次实测错误的 (b) 卡 ⇒ 立。`
    A worked example of lines 12–13 and 20 in the same section, which stay; both halves of the example are derivable from them.

Also rewritten rather than deleted: triage-duties.md 74 (派发前按生产者的答案改卡的范围与域标签。) keeps its content inside the new line (据答改卡范围、域与路由, now at first touch), and line 73 keeps the declared≠enforced producer question unchanged.

Dispatch hypotheses, measured

  • "Rule 2 can be appended to the 「只在至少一条成立时升级」 line or split into the adjacent 「或修复需破坏性/难回滚动作」 line" — falsified by measurement: those lines are 120 and 117 bytes, and the shortest self-contained spelling of the condition is 108 bytes, so it lands as one line inside the same enumeration (between the two), not as an independent rule line.
  • "Rule 3 is an extension of the REWORK cap line" — the REWORK line is 118 bytes, so the breaker went into the adjacent ESCALATE verdict line (rewritten, keeping its pointer) plus one conditions line, inside 〈复核〉; no new section.
  • "Rule 4 is mostly already in filing-gate.md" — confirmed for the reach: requirement; the security-label and highest-privilege-only sentences were absent (at 6befe19c, git grep -E '熔断|责任三|Responsibility:|声明式方案|不派码|不抬级' over .claude/skills/pm-dispatch/ exits 1; the control 升级与决策 hits 6 files), so one line landed, placed as the sibling of 「沿链继承只给上界」 so the two upper-bound statements read together and neither conflicts with 清单项三态 ① inheritance.
  • dispatch-runbook.md 〈派发词构造细则〉 was named as a landing spot for "the dispatch prompt carries the three answers". Not edited: the claim template line already says the dispatch prompt's ruling section repeats the three answers, the PM writes the claim immediately before the prompt, and a second sentence in the runbook would have cost a deletion there for a line with the same reader. execution-duties.md 〈候选与批次〉 line 13 (維护者裁决 → 派发词裁决分区) was not rewritten for the same reason.

Acceptance notes

  • references/lanes/hotcrm.md 30 and references/lanes/engine.md 32 carry lane-local copies of the "ask where the producer is" question for declared≠enforced cards; the new three-question line generalises them for every card at first touch. Left as they are (lane files, not in this card's surface; no conflict). carrier: none — noted, not filed.
  • AGENTS.md lists 安全/权限边界 on the human floor for auto-adjudication (triage-duties 95–96, SKILL.md 262) but the escalation enumeration had no security-boundary trigger before this PR; rule 2 is that trigger, narrowed to fixes that decide the boundary by guessing. Observation only.

Gates

Derived from this change set in the worktree with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at head 8cdefa6c: 21 commands, the same 21 the dispatch named. All 21 ran on 8cdefa6c (the tree was clean; the gates read the committed files) with the exit code captured before any pipe, and --ran reconciliation answered: "21 derived famil(ies) accounted for — 21 run, 0 NOT-MEASURED (a DERIVED zero — all 21 recorded an exit code and none of them is 3)". One first attempt was not a measurement: pnpm --filter @objectstack/lint run check:doc-formula-expressions exited 3 (PREREQUISITE NOT MET: @objectstack/formula and @objectstack/lint were not built in the fresh worktree); after turbo run build --filter=@objectstack/formula --filter=@objectstack/lint under the shared verify lock (VERDICT command-exit 0, held 133 s) the gate re-ran and exited 0 ("22 record-scoped formula example(s) across 461 files / 1384 TS blocks judged clean"). Selected verdict lines:

  • pnpm check:pm-skill-ratchet: "SKILL.md is 319 lines (ceiling 319; headroom 0)", "execution-duties.md is 183 lines (ceiling 183; headroom 0)", "seat-lifecycle.md is 96 lines (ceiling 96; headroom 0)", "triage-duties.md is 120 lines (ceiling 120; headroom 0)", "filing-gate.md is 58 lines (ceiling 58; headroom 0)"; the widest-table-row pin for SKILL.md stays at 342 bytes; no over-budget line (that red prints only on failure).
  • pnpm check:pm-skill-id-lint: "34 file(s) clean (pattern /#[0-9]{3,}/g)".
  • pnpm check:skill-frame-sync: "the one declared copy of the decision frame is internally coherent (.claude/skills/pm-dispatch/SKILL.md) … 4 axes … binding sentence present".
  • pnpm check:pm-governed-prose: "2 instruction surface(s) name all 6 registered governed surfaces … and claim no others".
  • pnpm check:nul-bytes: "scanned 10023 text file(s) … no raw ASCII control bytes".
  • pnpm check:doc-authoring: "sibling-package prose ids hold the baseline — 0 pinned site(s)".

check:skill-frame-freshness is not in the derived set; it compares this tree's frame with origin/main, and the frame block is byte-identical (md5 above). No package build, test or typecheck is owed: the diff touches no package. Changeset: none — .claude/** publishes nothing (fast lane), so the PR takes skip-changeset.

Landing

Every path is under .claude/**, so this is Tier S: the PR stays draft until the skills seat's contract-tier review record (Served-tier: CONTRACT_REVIEW_TIER, PASS) is on the thread or the card; the seat then lands it through the queue. No model identifier appears in this body or in the commit trailer pair.

维护者速读(草稿)

改了什么:给 PM 派发技能加了四条规则,共改五个文件、八行,逐行用删掉的重复行付账,每个文件行数不变。① 认领模板多一行 Responsibility:,派发前先答三问:风险出自谁的代码、平台是否已有正路、谁能碰到且今天有没有人在用;派发词的裁决区照抄这三答。② 三答都指向「别人的代码、已有正路、只有最高权限能碰到」时,默认只补文档或开决策卡,不派代码修复。③ 修复靠猜(字段名、值形状、模式表)来划安全边界的,先开决策卡、对照声明式方案,再谈派发。④ 熔断三条:独立安全复审连续两轮不过、改动超过首次复核规模两倍、上一轮修复引出新的高危,任一命中即暂停 PR、升级问你,你答复前不派下一轮;轮次报告逐 PR 列出命中项。⑤ 定级按可达面:security 标签本身不抬优先级;只有最高权限能碰到、又没人在用的发现至多 p3,可以只记录不修。分诊首触也要先答这三问。

为什么改:上一次把一张只影响仓库里不存在的插件驱动、只有平台管理员能看到的卡当成安全漏洞派了开发,复审四轮都没收住,改动长到四千行,最后作废改成补一句文档。成本花在开工之前没人问「这是谁的问题」,和开工之后没有东西能停下循环。这五处改动把这两个问题各放在席位必经的那一行上。

风险与代价(含回滚):风险是规则写得过短被误读 —— 每行不超过 120 字节,只能用缩略说法(如「他人代码」指第三方或用户代码,「至多 p3」对应「最多 low」)。代价是删了五行重复文本,每一行的规则都在 AGENTS.md 或同技能的另一处保留,PR 正文逐条列了归宿。回滚是单个 commit 的 revert,不涉及代码、门禁或 workflow。

席位意见:(留空,由席位填写)

你要做的:看一眼五段速读里的四条规则是否与你在 #21921 上的裁决一致;一致则由 skills 席按达档复核落地,不需要你合并。


Generated by Claude Code

…ening security review

Four rules land in the pm-dispatch protocol text, each paid in place against the line ratchet:
the claim template gains a `Responsibility:` line (whose code / platform path / who reaches it),
the escalation enumeration gains the document-not-defend exit and the no-heuristic-security-boundary
exit, the REWORK/ESCALATE verdicts gain the three circuit-breaker conditions, the round report lists
breaker hits per PR, triage asks the three questions at first touch, and the grading rules cap a
highest-privilege-only, no-current-user finding at p3 regardless of the security label.

Claude-Session: https://claude.ai/code/session_0181E4ZeZmWyknawnauxD2CE
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 Oct 6, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 6, 2026
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Oct 6, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 8cdefa6c2462751d694dfec1858014f460ef5238
Local-runs: none

Face reviewed: governed rule text (.claude/skills/pm-dispatch/**; Tier S — every path under .claude/**). Inputs: card #21929 (body and both comments), the #21921 rulings it rests on (comments 6007092527 and 6007152671), PR #21999's body and file list, and the net diff of 8cdefa6c against its merge-base 6befe19c (+8 / −8 across 5 files). Check-runs on the head at 2026-10-06T14:50Z: 30 completed (success or expected skip), 3 in progress (Lint & Repo Gates, Type Check · consumer gates, Type Check · debt ledger) — the landing waits on them. Nothing built, run or re-run here.

① Derived judgments

  • Accept set / public surface: none changed. The diff touches no package, no skills/**, no schema, no error code; .claude/** publishes nothing. Right.
  • Rule 1 (responsibility before dispatch): the claim-template field Responsibility: (three answers; n/a — not a defect card; the dispatch prompt's ruling section repeats them), the escalation condition at SKILL.md :214 (the three answers point at someone else's code, an existing platform path and highest-privilege-only reach ⇒ docs or a decision card, no code dispatch) and the triage first-touch line :74. Matches the decision: how a datasource driver with no shipped config contract keeps credentials out of metadata (declaration vs. key-name heuristic) #21921 rulings 「安全性应该由写代码的人控制,不应该我们盲猜」 and 「同意作废,文档补一句」, generalised as the card asked. Right. The claim readers in scripts/pm/check-half-states.mjs key on the Claim: and Thread-read: lines only, so the added key is inert to them. Right.
  • Rule 2 (no security boundary on a heuristic): the escalation condition at SKILL.md :215 — a fix that decides the boundary by key names, value shapes or pattern lists ⇒ a decision card comparing a declaration-based approach first. Matches 「不应该我们盲猜」. Right.
  • Rule 3 (circuit breaker): execution-duties :182 ESCALATE rewritten (any breaker hit ⇒ the PR pauses, no next round before the maintainer answers) and :183 the three conditions (independent security review failed two rounds in a row / diff past twice its first reviewed size / the previous round's fix introduced a new HIGH); seat-lifecycle :68 lists hits per PR in the round report. The card's conditions and consequence, in substance verbatim. Right.
  • Rule 4 (price by reach): filing-gate :43 under 「沿链继承只给上界」 — the security label does not raise the grade; highest-privilege-only reach with no current user ⇒ at most p3, may be recorded without a fix. Consistent with the existing reach-less ⇒ p3 rule (triage-duties :47) and with ledger inheritance read as an upper bound. Right — and this is the one line whose generalisation goes past the verbatim decision: how a datasource driver with no shipped config contract keeps credentials out of metadata (declaration vs. key-name heuristic) #21921 rulings (which closed one P2 card); it is the card's rule 4 as filed and triage-graded, and the 速读 draft in the PR body is the maintainer's veto window.
  • Deletions (5), each with its surviving home verified on origin/main: the SKILL.md 报告契约 reach: restatement → filing-gate :12–:14 and :20, triage-duties :47–:48 (the family-card half → SKILL.md :285); the 机械守卫索引 row git-history.mjs → AGENTS.md :393 (answer or REFUSE, historyHorizon()); the row guard-main-checkout / guard-shared-stash → AGENTS.md :224–:231 and :323–:329, and the SKILL.md 红线 line; execution-duties :71 (Clause-②: yes ⇒ at least minor) → AGENTS.md Post-Task Checklist step 3 (「yes takes at least minor」); filing-gate :15 判例 → derivable from :12–:13 and :20. No rule lost. The one phrase without a literal home, 「同轮报告互读」, is a method whose rule (one card per family) stays at SKILL.md :285.
  • Widths of the 7 new or rewritten prose lines: 120 · 108 · 110 · 114 · 112 · 113 · 117 bytes (LC_ALL=C awk); the template field sits inside a fence. The four-axis frame block is untouched (md5 abff5f852c8fd09b79ec0623439aa4f0 on the head). No issue number in any added line. Right.

② Semver level

Clause-②: no on the claim (6018096077) and at PR body line 2 — right: no published contract moves. skip-changeset on the PR — right: .claude/** is the fast lane and no package publishes. No existing changeset is edited.

③ Boundary flags

  • Deviation 1 (dispatch-runbook.md not edited): accepted — the template field's parenthetical already binds the dispatch prompt for the same reader; a second line is not owed.
  • Deviation 2 (two PM hypotheses falsified by byte measurement — rule 2 as its own condition line, rule 3 on the ESCALATE line plus one conditions line): accepted — both land inside the enumeration / section intended.
  • Deviation 3 (the spellings 至多 p3 and 他人代码): accepted — p3 is the repo's lowest grade, and the long spelling does not fit 120 bytes.
  • Deviation 4 (base 6befe19c, one commit after dispatch, outside the surface): accepted.
  • Deviation 5 (the model-free commit trailer pair): correct per the dev definition.
  • Acceptance notes (2, carrier: none): the lane-file producer questions and the human-floor observation — notes only, no card.
  • open_questions: none. The sibling in flight on the same two files (skills(pm-dispatch / os-dev): user-visible UX defects are class (a) — a reproducible, fix-site-named UX defect is filed like a functional one; pure taste and redesign are not #21992, PR to come) has been told which lines this diff edits; the later lander merges once more before enqueue.

Implemented-by: claude/issue-21929-judge-responsibility-before-dispatch
Reviewed-by: session_0181E4ZeZmWyknawnauxD2CE

VERDICT: PASS

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 6, 2026 15:15
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 6, 2026
Merged via the queue into main with commit 1bc6ca1 Oct 6, 2026
36 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-21929-judge-responsibility-before-dispatch branch October 6, 2026 15:42
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Oct 7, 2026
…led like a functional one when it reproduces on a public surface with a named fix site (objectstack-ai#22000)

Fixes objectstack-ai#21992
Clause-②: no

## What changes

Three governed files under `.claude/` state the same boundary for their
three readers: a **user-visible UX defect is class (a)**, on equal
footing with a functional defect, when it reproduces stably on a public
surface, names its fix site, and its expected-vs-actual does not rest on
taste; pure taste, redesign / new-feature proposals (→ ②) and
performance observations with no user-visible cost are not cards. The
ruling's three properties are the card's; the wording is tightened to
the ratchet's 120-byte line cap.

Model tier (derived, not recalled): `node scripts/pm/dispatch-gates.mjs
--tier --repo objectstack-ai/objectstack .claude/agents/os-dev.md`
prints "Model tier — MANDATORY … — clause ① (2026-08-20 narrowing): the
dev-agent definition is protocol semantics". Tier S (every path under
`.claude/**`): this PR stays draft until the owning seat's contract-tier
review of record.

### Lines added (byte widths measured against the 120-byte cap)

| file | inserted after (at `origin/main` 6befe19) | line added | bytes
|
|---|---|---|---|
| `references/filing-gate.md` | `:12`, the ① line | `- ①
含用户可见的体验缺陷,与功能缺陷同等:界面上稳定复现、落点具名、预期不凭审美。` | 119 |
| `references/filing-gate.md` | the line above | `- ⛔
不是卡:纯审美偏好、重设计与新功能提议(走 ②)、无用户可见代价的性能观察。` | 112 |
| `references/filing-gate.md` | the ⛔ line above — closing the ① group
(moved there in `2a241332`; the (b) 判例 line at `:15` is deleted by PR
objectstack-ai#21999 and is no longer this line's anchor) | `- 判例:仪表盘刷新按钮独占一行、首屏白占约
120px ⇒ 立;「配色换个好看的」⇒ 不立。` | 115 |
| `references/triage-duties.md` | `:43`, the (a) boundary line | `- (a)
不分功能与体验:能用但用户可见地错(截断、遮挡、白占首屏、误导文案)也是 (a)。` | 115 |
| `.claude/agents/os-dev.md` | `:42`, the (a)/(b) line | ` - (a)
含用户可见的体验缺陷(截断、遮挡、白占首屏、误导文案),须复现且落点具名。` | 114 |

**Deviation from the card's draft, declared.** The card drafted four
filing-gate lines (+4). The stand-alone forms line
(「体验缺陷形态:截断、遮挡、白占首屏、文案与页面矛盾、删除不点名对象、显示原始值」, 120 bytes) is not added
here: the forms travel in the triage-duties and os-dev parentheticals,
and the 判例 line carries the ruling's concrete case. Reason: filing-gate
holds exactly three deletable lines whose rule survives elsewhere (table
below); a fourth added line would have needed a ceiling raise in
`scripts/pm/check-skill-line-ratchet.mjs`, a file the dispatch fenced
off. The three ruled properties stand in every file; no re-wrap bought a
line. Mechanism probes the dispatch asked for: folding the ⛔ line into
the existing 「⛔ 不是卡」 line at `:20` measures 130 bytes, and folding the
triage line into `:43` measures 130 bytes — both over the cap, so both
stay separate lines as drafted; os-dev `:42` (113 bytes) is untouched
and the new line sits under it as a sub-item.

### Lines deleted, with each rule's surviving home

| file:line (at 6befe19) | deleted line | surviving home |
|---|---|---|
| `filing-gate.md:30` | `收到 429 或次级限流 ⇒ 该席本 fire 停写,并把停写记在座位贴上。` |
`SKILL.md:93` 「429 即停写」(全体座位的不变量) + `triage-duties.md:117`
「限流/重试类运维细节只进座位贴和触发器」 |
| `filing-gate.md:31` | `关单 ⛔ 永不由脚本循环连发:须维护者确认的分组,且逐笔之间留间隔。` |
`filing-gate.md:28` (维护者确认的十张一组, kept) + `SKILL.md:93` 「节奏 ≥3 秒/笔、每账号每小时
≤40 笔」 + `AGENTS.md` "Every GitHub write leaves through `scripts/pm/`"
(write-pace.mjs serialises and spaces every write verb; close-cards owns
its writes) |
| `filing-gate.md:32` | `用户类写绑作者:封号则其卡与评论按作者 404,故一个 fire 的首写回读
user.type。` | `platform-readings.md:133` 「类只认每次写回读的
user.login/user.type」(every write — a superset of the first write) +
`:135` 「封号隐藏其全部评论…」 + `:166–171` (停用销毁其名下 PR、卡与评论). The consequence line
`:33` 「读到 User ⇒ 记座位贴、本 fire ⛔ 不立新卡…」 stays. |
| `triage-duties.md:84` | `标签/assignee 写恒经
scripts/pm/label-write.mjs(四步、回读);⛔ 永不 MCP issue_write(锁 1 已拒)。` |
`rest-channel.md:44` (⛔ 永不 MCP issue_write(锁 1 已拒)) + `SKILL.md:92`
「内容写只走 REST 代理,⛔ 无 MCP 写」 + `execution-duties.md:59` + `AGENTS.md`
write-gate paragraph (label-write owns its writes) + `os-dev.md:304`
(the four steps) |
| `os-dev.md:203` | `⛔ 永不 git stash;替代拼写(wip commit / patch)、机制与 hook
住每会话注入的 CLAUDE.md。` | `AGENTS.md` Multi-agent working discipline (the
`git stash` paragraph, `guard-shared-stash.sh`, the replacements block)
— the file os-dev.md declares binding at its line 7; `SKILL.md:31`;
`os-dev.md:201` still names the stash stack as shared |

### line_budget

| file | before → after | ceiling | headroom | ceiling action |
|---|---|---|---|---|
| `references/filing-gate.md` | 58 → 58 (+3 / −3) | 58 | 0 | none |
| `references/triage-duties.md` | 120 → 120 (+1 / −1) | 120 | 0 | none |
| `.claude/agents/os-dev.md` | 402 → 402 (+1 / −1) | 402 | 0 | none |

No ceiling raised, no `scripts/**` touched; the fallback ruling quote
the card names for a raise was therefore not spent.

### Sibling in flight — region overlap, recorded

`claude/issue-21929-judge-responsibility-before-dispatch` at `8cdefa6c`
(its card objectstack-ai#21929 remains open and is not addressed here) also edits
filing-gate.md and triage-duties.md. Its hunks: filing-gate adds one
定级判据 line (its declared region) and **deletes `filing-gate.md:15`, the
(b) 判例 line — outside its declared region, and formerly the anchor of
this PR's 判例 line; since `2a241332` the two PRs' hunks are two lines
apart, and a read-only `git merge-tree` of `2a241332` × `8cdefa6c` is
conflict-free (tree `032fb524`; filing-gate 58 / triage-duties 120 after
stacking). `origin/main` has not moved (still `6befe19c`), so there was
nothing to merge before opening. Whichever lands second resolves the
adjacent hunk by stacking both intents — their deletion of the (b) 判例
line and this PR's UX 判例 line — and re-runs `check:pm-skill-ratchet`;
after stacking, filing-gate stays at 58.

## Verification

Head `2a241332` (the second commit moved one line inside filing-gate.md;
the report comment 6018992259 carries the gate run on this head — the
first run below was on `8014e8ba`). Every command below ran on this tree
with the exit code captured before any pipe. The derived families came
from `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` with no paths (21 derived); `--ran`
reconciled 21 of 21 run, 0 unrun; the dispatch named three more
(`pm-expected-skips`, `pm-governed-prose`, `skill-frame-freshness`),
also run.

- `pnpm check:pm-skill-ratchet` :: exit 0 — filing-gate 58/58,
triage-duties 120/120, os-dev 402/402, headroom 0; no prose line over
120 bytes.
- `pnpm check:pm-skill-id-lint` :: exit 0 — 34 files clean. `pnpm
check:agent-model-declared` :: exit 0 — os-dev.md → opus. `pnpm
check:nul-bytes` :: exit 0.
- `node scripts/check-closing-keyword-parity.mjs` :: 0 and `--self-test`
:: 0 · `node scripts/check-comment-mask-corpus.mjs` :: 0 · `node
scripts/pm/check-governed-queue-guard.mjs --self-test` :: 0 · `node
scripts/pm/check-harness-current.mjs --self-test` :: 0 · `pnpm
check:pm-governed-merges` :: 0 · `pnpm check:pm-expected-skips` :: 0 ·
`pnpm check:pm-governed-prose` :: 0 · `pnpm check:agent-test-spelling`
:: 0 · `pnpm check:commit-card-trailers` :: 0 · `pnpm
check:doc-authoring` :: 0 · `pnpm check:gitlink-declared` :: 0 · `pnpm
check:watch-hint-literal` :: 0 · `pnpm check:refd-timer-probe` :: 0 ·
`pnpm check:skill-frame-sync` :: 0 · `pnpm check:skill-frame-freshness`
:: 0 · `pnpm check:cross-package-test-inputs` :: 0 · `pnpm
check:driver-memory-census` :: 0 · `pnpm check:pm-half-states` :: 0
(4912 self-test cases).
- `pnpm --filter @objectstack/lint run check:doc-formula-expressions` ::
exit 3 on the first run, PREREQUISITE NOT MET (formula/lint not built —
nothing measured); then `pnpm exec turbo run build
--filter=@objectstack/formula --filter=@objectstack/lint
--concurrency=2` under `scripts/pm/os-verify-lock.sh` (VERDICT
command-exit 0), and the rerun :: exit 0 (58 self-test cases; 22
examples clean).

The diff touches no package, so the dependency-closure build (①) is
empty and no package test (②) is owed. Changeset: none — `.claude/**`
publishes nothing; `skip-changeset` is requested through `label-write`.

## Acceptance notes

- The sibling branch's deletion of `filing-gate.md:15` falls outside the
region its claim declared (〈定级判据〉). Noted for the owning seat, not
filed; `carrier:` the reviewer of the objectstack-ai#21929 PR.
- A dispatch-internal tension, resolved without choosing a side: the
card's fallback (raise the file's ceiling with the ruling quoted) lives
in `scripts/pm/check-skill-line-ratchet.mjs`, which the dispatch's file
fence excludes. Paying every added line by deletion made the fallback
unnecessary; if the owning seat wants the forms line too, that is one
more filing-gate line and a 58→59 raise citing 「同意,立卡起草这条规则」.

## 维护者速读(草稿)


**改了什么**:三份内部协议文件(立卡门、分诊职责、开发代理定义)各加一条:用户看得见的体验缺陷(截断、遮挡、首屏白占、误导文案)与功能缺陷同等,属于可立卡的
(a)
类;仍须在公开界面稳定复现、落点具名、预期与实际不凭审美;纯审美偏好、重设计/新功能提议、无用户可见代价的性能观察不是卡。立卡门另加一条判例:仪表盘刷新按钮独占一行、首屏白占约
120px ⇒ 立;「配色换个好看的」⇒ 不立。

**为什么改**:维护者裁决(照抄不译):「仪表盘空白
很严重啊,这种为什么不处理,是不是标准有问题?这么明显的用户体验相关的为题」「同意,立卡起草这条规则」。此前三处类定义都没说体验缺陷算不算
(a),席位读窄了,七个真实体验缺陷一度未立卡。

**风险与代价(含回滚)**:三文件行数不变(58 / 120 /
402),没抬任何上限;每加一行就删一行,被删的五行其规则都在别处仍然成立(上表逐条点名归宿),删掉的只是重复的指针。风险在于席位可能把「体验缺陷算卡」读宽
—— 第二、三条就是围栏。回滚即 revert 本 PR 的一个 commit。兄弟 PR(objectstack-ai#21929
在飞)也动了其中两份文件,后落地的一方合一次 main 并重跑行数门禁。

**席位意见**:

**你要做的**:本 PR 全在 `.claude/**`(Tier
S),由席位达档复核后入队落地,无需你亲手合并。若你希望「体验缺陷形态」的完整清单(截断、遮挡、白占首屏、文案与页面矛盾、删除不点名对象、显示原始值)也进立卡门,那是多一行并抬
filing-gate 上限 58→59,请一句话告知。

Implemented by the `os-dev` subagent of
`session_0181E4ZeZmWyknawnauxD2CE` (branch
`claude/issue-21992-ux-defects-are-class-a`); the three body corrections
named in report comment 6018992259 (head, the 判例 row's anchor, the
sibling-overlap sentence) were written by the seat in that session.

---------

Co-authored-by: os-dev <steve@objectstack.ai>
Co-authored-by: Claude <noreply@anthropic.com>
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

Development

Successfully merging this pull request may close these issues.

skills(pm-dispatch): judge responsibility before dispatch, and stop a PR whose security review keeps reopening

2 participants