Skip to content

docs(pm-dispatch, os-dev): a user-visible UX defect is class (a) — filed like a functional one when it reproduces on a public surface with a named fix site - #22000

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-21992-ux-defects-are-class-a
Oct 6, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-21992-ux-defects-are-class-a

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #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 #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 #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 skills(pm-dispatch): judge responsibility before dispatch, and stop a PR whose security review keeps reopening #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(#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.

…led like a functional one when it reproduces on a public surface with a named fix site

filing-gate.md: ① admits UX defects on equal footing; a ⛔ fence keeps taste,
redesign (→ ②) and cost-free perf observations out; a 判例 line records the
dashboard case. triage-duties.md and os-dev.md state the same boundary for
the triage seat and the dev. Every added line is paid by deleting a line
whose rule already lives elsewhere (write pacing / write identity /
label-write channel / git stash), so all three ceilings stay at 58 / 120 / 402.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0181E4ZeZmWyknawnauxD2CE
@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
…ng under the (b) 判例 line

The sibling branch in flight deletes the (b) 判例 line; anchoring the new
case under it would make the two hunks adjacent. Placed after the ⛔ fence,
the ① group reads ①-extension → fence → case, and two unchanged lines
separate it from the sibling's deletion.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0181E4ZeZmWyknawnauxD2CE
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 2a241332d3375c7bb4489cd024e7697abea9b737
Local-runs: probe — one read-only git merge-tree --write-tree in the seat's checkout, of this head against the sibling governed PR #21999's head 8cdefa6c and against origin/main, to read whether the two in-flight edits of filing-gate.md and triage-duties.md stack without conflict; nothing built, run or re-run

Face reviewed: governed rule text (.claude/skills/pm-dispatch/references/** and .claude/agents/os-dev.md — protocol semantics; Tier S, every path under .claude/**). Inputs: card #21992 (body and the triage grade 6017868609), PR #22000's body and file list, the net diff of 2a241332 against its merge-base 6befe19c (+5 / −5 across 3 files), and the two report comments (6018992259 authoritative, superseding 6018856701). Check-runs on the head at 2026-10-06T15:03Z: 25 completed (success or expected skip), 1 in progress (Lint & Repo Gates) — the landing waits on it.

① Derived judgments

  • Accept set / public surface: none changed. No package, no skills/**, no schema, no error code; the os-dev.md frontmatter (model:) is untouched. Right.
  • Property (1), UX defects are class (a) on equal footing: filing-gate :13 (「① 含用户可见的体验缺陷,与功能缺陷同等…」), triage-duties :44 (「(a) 不分功能与体验…」), os-dev :43 (sub-item of the (a)/(b) line). Matches the ruling 「同意,立卡起草这条规则」 and the three properties the card names as the ruling's. Right.
  • Property (2), still owing a stable public-surface repro, a named fix site and a taste-free expected-vs-actual: carried inside each of the three lines (「稳定复现、落点具名、预期不凭审美」 / 「能用但用户可见地错」 / 「须复现且落点具名」); reach: for a UX defect stays the existing 「公开入口 … 界面」 arm, no new reach type. Right.
  • Property (3), the fence: filing-gate :14 (「⛔ 不是卡:纯审美偏好、重设计与新功能提议(走 ②)、无用户可见代价的性能观察。」). Right.
  • The 判例 line (filing-gate :15, the dashboard case ⇒ 立 / 「配色换个好看的」⇒ 不立) closes the ① group after the fence instead of hanging under the (b) 判例 line that PR docs(pm-skill): judge responsibility before dispatch, breaker on reopening security review #21999 deletes. Probe: git merge-tree --write-tree 8cdefa6c 2a241332 exit 0, tree 032fb524; against origin/main f0022c46 exit 0, tree 4ed610e0; in the stacked tree filing-gate.md is 58 lines and triage-duties.md 120 — both at their ceilings, so the two PRs land in either order without a ratchet breach. Right.
  • The card drafted four filing-gate lines; three landed. The stand-alone forms line (six named forms) is not added; four of its forms travel in the triage-duties and os-dev parentheticals (截断、遮挡、白占首屏、误导文案) and the 判例 line carries the concrete case; 「删除不点名对象」 and 「显示原始值」 are not spelled anywhere in the landed text. The ruling's three properties are intact and the card says the wording is the lane's to tighten; the forms list was illustrative. Accepted — recorded so the next card on this face knows the two forms are unnamed.
  • Deletions (5), each surviving home verified on origin/main: filing-gate :30 (429 ⇒ stop writing, record on the seat post) → SKILL.md :93 「429 即停写」 + triage-duties :117 (限流/重试类运维细节只进座位贴); filing-gate :31 (closures never by a script loop; pacing) → filing-gate :28 (十张一组, kept) + SKILL.md :93 (≥3 秒/笔) + AGENTS.md :420 (write-pace.mjs serialises and spaces every write verb); filing-gate :32 (first write of a fire reads back user.type) → platform-readings :133 (every write's user.login / user.type read back) and :135, the consequence line :33 kept; triage-duties :84 (label-write four steps; ⛔ MCP issue_write) → SKILL.md :92 and the 标签写恒四步 invariant, rest-channel :44, execution-duties, os-dev :304, AGENTS.md :420–:421; os-dev :203 (⛔ git stash) → AGENTS.md :323–:329 and the SKILL.md 红线 line, with os-dev :201 still naming the stash stack as shared and guard-shared-stash.sh enforcing it. No rule lost. Right.
  • Widths of the 5 added lines: 119 · 112 · 115 · 115 · 114 bytes (LC_ALL=C awk), none over the 120 cap; no issue number in any added line; check:agent-model-declared unaffected (frontmatter untouched). Right.

② Semver level

Clause-②: no on the claim (6018313288) 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

  • The coordinator correction (second commit 2a241332, the 判例 line moved off the (b) 判例 anchor): accepted; the probe above is its evidence.
  • 3 filing-gate lines instead of 4, and the card's ceiling-raise fallback not exercised: accepted — a raise would edit scripts/pm/check-skill-line-ratchet.mjs, outside the fence, and 新增门禁/棘轮默认否; the dev named the one-line raise (58 → 59) in the body in case the seat wants the forms line — the seat does not: the three properties stand without it.
  • Mechanism probes (folding the fence into filing-gate :20 or the triage line into :43 measures 130 bytes each — over the cap): accepted, separate lines are right.
  • origin/main advanced to f0022c46 during the pr_create stroke; no merge performed; merge-tree against it is clean (above): accepted.
  • Fifth GitHub write (the superseding report comment, because the first named the pre-correction head and placement): accepted — GitHub is the report's authoritative source and the first comment is explicitly superseded.
  • The model-free commit trailer pair and the session-URL footer instead of the harness reminder: correct per the dev definition.
  • PR body corrections the dev could not write (dev writes the body once): the seat writes them — Head 8014e8ba → 2a241332; the 判例 row's anchor cell; the sibling-overlap sentence.
  • Acceptance note (carrier: the reviewer of PR docs(pm-skill): judge responsibility before dispatch, breaker on reopening security review #21999): docs(pm-skill): judge responsibility before dispatch, breaker on reopening security review #21999 deleted filing-gate.md:15 outside the region its claim declared — read by this seat, which is that reviewer; noted in docs(pm-skill): judge responsibility before dispatch, breaker on reopening security review #21999's record as a verified deletion with a surviving home; no card.
  • open_questions: none.

Implemented-by: claude/issue-21992-ux-defects-are-class-a
Reviewed-by: session_0181E4ZeZmWyknawnauxD2CE

VERDICT: PASS

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

1 participant