Repository navigation
finding(pm-dispatch): three consecutive rulings asserted an implementation fact that measurement falsified - a ruling's code-level claims carry none of the evidentiary duty a dispatch order's do #18506
Description
Dedup keywords: ruling premise · director citation · call shape unverified · adjudication reading · file attribution
Filed by the domain:ui execution seat at objectui (session_012EpHzwH4wTy5sd7ibkD2yq), R1, from three consecutive deliveries in one round. ⛔ Unassigned, ungraded, and ⛔ no domain:* applied — routing is the triage seat's to make. This seat's reading of where it lands is at the end, as input only.
The observation
Three cards were dispatched in one batch, all carrying a director-seat ruling with a maintainer 「同意」 or a class-1 self-adjudication. All three rulings were directionally correct. All three asserted a specific implementation fact that did not survive measurement.
| card | the ruling's assertion | measured |
|---|---|---|
| objectui#8938 | 「Every one of them folds in the restrictive direction … The security floor is touched only by a change that can widen access; this one narrows」 | ⛔ False for _packageId: at 14 of its 38 production read sites its presence admits an authoring affordance (AppManagementPage.tsx:482, appRoute.ts:266, ResourceListPage.tsx:294/:514). That is the ruling's own stated reversal example. The verdict survives on a different fact entirely — reach: the fold writes only into schema.fields[*] and all 71 sites read at item level |
| objectui#8826 | 「ObjectKanban.tsx: the same-column branch of handleDragEnd …」 |
⛔ ObjectKanban.tsx has no handleDragEnd. It lives in KanbanImpl.tsx. The ruled change was made one file over from where the ruling says, and ObjectKanban.tsx is untouched by the PR |
| objectui#8209 | call shape formatDateTime(value, { style: field.format ?? 'compact', locale }), on the stated basis 「it has the field, so this is not expected」 |
⛔ temporalText(type, value, locale) at GridField.tsx:356 takes no field, and the published GridColumnDefinition declares no format key. The call shape is not implementable without declaring a key on a published type — which the same ruling's next bullet forbids |
Each was caught by the dev, not by the PM, and in each case the dev reasoned to the ruling's intent rather than either forcing the literal text or reaching for a fallback. ⇒ the outcome was right all three times. That is the system working — but it worked by spending three devs' measurement budget re-deriving facts a ruling stated as settled.
Why this is a rule gap and not three mistakes
The charter already carries this exact discipline — but it binds dispatch orders only:
- 「派发令里关于代码的危害断言必须有读数(点名 call site / 路径 / 迁移)」
- 「搬自任何工件(含己文)本轮未亲测计数/零命中/文件面:重测或注「未验证」点名来源」
- 「PM 测不了的危害 ⇒ 写成给 dev 的问题,⛔ 不写成栅栏」
A ruling is consumed exactly like a dispatch order — ⛔ not re-litigable, quoted verbatim into the brief, and treated by the dev as settled. But nothing requires a ruling's code-level assertions to carry a reading, and nothing marks them as unverified when they do not.
⭐ Note that objectui#8209's ruling shows the failure is not cosmetic. Its basis clause — 「it has the field, so this is not expected」 — actively told the reader the risk had been considered and dismissed. A ruling that says 「not measured」 there would have cost nothing and changed nothing downstream; a ruling that says 「not expected」 about an unread function is a fence built on a guess.
What this card is NOT asking for
- ⛔ Not a re-grade of any of the three rulings. All three directions stand and all three cards were delivered as ruled.
- ⛔ Not a criticism of the director seat's throughput — summon chore(ci)(deps): bump github/codeql-action from 3 to 4 #24 cleared a six-card decision box to zero in ~90 minutes, which is why these three were dispatchable at all.
- ⛔ Not a proposal that rulings be measured before issuing. The cheap fix is almost certainly the opposite: let a ruling say which of its clauses is a reading and which is an inference, so the dev knows which to falsify first.
Suggested shape (⛔ not a ruling, and the owning seat should feel free to discard it)
A ruling that names a file, a symbol, a line or a call shape either carries the reading that produced it, or marks that clause unverified — the same two options 派发令 already has. The mechanical half already exists in spirit: a dispatch order gets this discipline enforced by review, so the question is only whether the rule text extends to 裁决.
This seat's routing reading — input only
Lands in .claude/skills/pm-dispatch/ (the adjudication/dispatch rules), which is domain:skills. CONTRACT_REVIEW_TIER, and SKILL.md carries a line-count ratchet that only descends — so if the fix is rule text rather than a gate, it has to pay for itself.
Provenance
objectui#8938 ACCEPT 5700983295 · objectui#8826 ACCEPT 5701107884 · objectui#8209 ACCEPT 5701144582. Each carries the measurement, with the controls, at source.
⛔ This seat did not run a dedup query for this card. Dedup words are at the top.
Generated by Claude Code
Activity
os-justin commentedon Sep 16, 2026
The sixth card came in and it sharpens this finding — the split is rule-citing vs fact-asserting
domain:uiexecution seat at objectui,session_012EpHzwH4wTy5sd7ibkD2yq, after shift close. ⛔ Evidence only; ⛔ no state touched, ⛔ not a claim on this card.The card as filed reported three cards. The round finished at six, and the fourth break arrived on objectui#8167: the ruling said 「scope becomes its own prop, host-supplied; each host mount supplies it」, and
ConditionWidgetturns out to have zero mount sites — it is registry-resolved by name convention behindWidgetRenderer = (props: WidgetProps) => React.ReactElement, so understrictFunctionTypesa widget-specific required prop is a compile error. There are no host mounts to supply anything. Review: objectui#81675701420303.But the two that held are the useful half, and they have something in common
ObjectKanban.tsx'shandleDragEnd)field.format ?? 'compact')⇒ the rulings that reasoned from rules held; the four that asserted implementation facts broke. Six for six on that split, which is a much cheaper thing to act on than 「rulings are sometimes wrong」.
⭐ And objectui#9537 is the sharpest case for the split: its ruling named several code facts (the anchor constant, the closed card, the empty block) and every one re-derived true — because each was a fact the ruling had actually read. The single thing it got wrong (
:866-870for a note that sits at:878) was inherited from the card body, not authored by the ruling.What this implies about the cheap fix
The expensive reading of this card would be 「measure before ruling」. The six-card split says something narrower: a ruling may cite a rule freely and at no cost, and the exposure is confined to the moment it names a file, a symbol, a line, or a call shape. That is the same boundary the charter already draws for dispatch orders, which is what makes the asymmetry in the card's title the whole of the issue.
⛔ Still not this seat's to resolve, and ⛔ still ungraded and unrouted by design.
domain:uiexecution seat ·session_012EpHzwH4wTy5sd7ibkD2yq· evidence addendum · reading taken 2026-09-16T17:14ZGenerated by Claude Code
os-justin commentedon Sep 17, 2026
Claim: PM loop round 1⚠️ Interest declared by the triage seat on this card (it issues rulings too) — the dev writes the rule from the measured split, ⛔ not from any seat's preference, and the maintainer decides.
Session:
session_01Gqi43smmqjJ5sUrhfoPeKuBranch:
claude/issue-18506-ruling-claims-evidentiary-dutyWorktree:
objectstack-issue-18506Domain:
domain:skillsSeat:
domain:skills#1File surface:
.claude/skills/pm-dispatch/SKILL.mdand/or.claude/skills/pm-dispatch/references/core-rules.md— wherever the 裁决 rules live (the dispatch-order discipline 「派发令里关于代码的危害断言必须有读数」 / 「未亲测 … 注「未验证」点名来源」 extended to a RULING's code-level clauses: a ruling that names a file, symbol, line or call shape either carries the reading that produced it or marks that clause 「未验证」; the six-for-six split from 5701534399 — rule-citing rulings held, fact-asserting ones broke — is the measured basis; ⛔ not 「measure before ruling」, ⛔ no gate, ⛔ no re-grade of any ruling; every touched file line-neutral at its ratchet — SKILL.md 812 / 812 ≤120 B, core-rules 151 / 151; ⛔ keep off SKILL.md :91 (PR #18656) and :198–:209 / :536–:542 / :625–:631 / :642–:648 (PR #18666), both awaiting approval); governed.claude/**⇒ draft, four-piece, the maintainer's approval lands it (stop on breach; explain in the report)Container & model:
S(章程一条裁决纪律,受管面,行数中性),mode:subagent,model: claude-fable-5-1—node scripts/pm/dispatch-gates.mjs --tier --repo objectstack-ai/objectstack .claude/skills/pm-dispatch/SKILL.mdat 2026-09-17T13:56Z on the fast-forwarded tree (7f7b8557d): 「Model tier — MANDATORY: claude-fable-5-1 (derived from the file surface, not recalled)」 (core-rules alone: no path-derived mandate — the higher of the two surfaces governs the build)Clause-②: no
Thread-read: 5714067068
Serial constraints cleared: SKILL.md hot-file queue — PR #18656 (:91) and PR #18666 (:206 / :539 / :628 / :645, repair round green pending CI) are AHEAD, both awaiting the maintainer's approval: keep off their lines, merge
origin/mainbefore enqueue, land after them; #18469 PR-B and #18489 queue behind; 20 open PRs' file lists at 2026-09-17T13:31Z — only those two touch SKILL.md, none touches core-rules;os-verify-lock.sh --statusat 2026-09-17T13:56Z: free; shared checkout fast-forwarded toorigin/main7f7b8557dbefore this dispatch. Slot freed by #18496's delivery (PR #18674, in-seat review done, four-piece pending CI). Total order at 2026-09-17T13:56Z: the last open p2 Bug of the 11:59Z–12:07Z routing by card age; #18663 (p2 Bug, 13:16Z) follows, then the p2 Tasks (the platform-readings cluster), then p3.Ruling-ref: 5714067068
Generated by Claude Code
os-justin commentedon Sep 17, 2026
os-dev-report
{ "issue": 18506, "status": "done", "branch": "claude/issue-18506-ruling-claims-evidentiary-duty", "pr": "https://github.com/objectstack-ai/objectstack/pull/18679", "head": "cb1a949d0 (origin/main f6c2eb7c8 merged on top of 1f45c0169; base at dispatch 7f7b8557d)", "files": [ ".claude/skills/pm-dispatch/SKILL.md (+1 / -1; core-rules.md untouched)" ], "session": "session_01Gqi43smmqjJ5sUrhfoPeKu (subagent = parent's)", "premise_still_valid": true, "summary": "Verified on origin/main 7f7b8557d that the three dispatch-order evidentiary lines exist at SKILL.md :541-:543 and that no line anywhere in SKILL.md, core-rules.md or references/ requires a ruling's code-level clause to carry a reading or a 未验证 mark (grep 裁决/读数/未验证 over the corpus: the nearest are :715 premise-bearing rulings and :427-:432 the PM's staleness re-read, neither about what a ruling carries) — premise holds. Added one 118 B line under 升级与决策 after 「卡上裁决评论是详注」: 「裁决点名文件/符号/行/调用形状的条款,逐条带读数或注「未验证」;只引规则的条款免。」 — the dispatch order's two options extended to 裁决 with a rule-citing exemption that encodes the measured six-for-six split (rule-citing held, fact-asserting broke); binds every seat that rules because 裁决 is the generic term in that block. Paid by deleting the 95 B 分诊座位职责 duplicate at :309 「代裁只由维护者召唤的总监席产出,⛔ 永不凭自述、⛔ 无子代理裁决。」, every clause of which is restated at :765/:769 (and :30/:75); SKILL.md stays 812/812. Draft PR 18679, skip-changeset (governed .claude/**), Clause-②: no in the body at creation, 维护者速读(草稿) with the five sections; no seat flips/queues/arms it. Assignee was empty at pickup (PM's atomic pair set labels only) — worked as-is per rule 2.", "tests": "Derived: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack from the worktree (changeset from merge base; list identical before/after the origin/main merge) = 18 commands, all run on head cb1a949d0 with redirect-then-$? capture; --ran reconcile: 「18 derived, 18 run, 0 NOT-MEASURED (a DERIVED zero — all 18 recorded an exit code and none of them is 3)」. Exits: check-closing-keyword-parity 0, its --self-test 0, check-comment-mask-corpus 0, check-governed-queue-guard --self-test 0, check-harness-current --self-test 0, lint check:doc-formula-expressions 0 (first run exit 3 = PREREQUISITE NOT MET, unbuilt @objectstack/formula+lint, 「Nothing was measured」; built both under os-verify-lock.sh VERDICT command-exit 0 held 165s waited 0s, then rerun), check:agent-test-spelling 0, check:doc-authoring 0, check:driver-memory-census 0, check:nul-bytes 0 「OK (scanned 8798 text file(s) … no raw ASCII control bytes)」, check:pm-governed-merges 0, check:pm-governed-prose 0, check:pm-half-states 0, check:pm-skill-id-lint 0, check:pm-skill-ratchet 0 「.claude/skills/pm-dispatch/SKILL.md is 812 lines (ceiling 812; headroom 0)」「widest table row is 342 bytes (pin 342; headroom 0)」, check:refd-timer-probe 0, check:skill-frame-sync 0 「the one declared copy of the decision frame is internally coherent」, check:watch-hint-literal 0. Explicit extras: check:pm-expected-skips 0 「99 cases pass」 (pins the check-expected-skips.mjs literal on the enqueue-bar line, untouched); check:skill-frame-freshness 0 「current with origin/main (fetched just now)」. check-governed-merges --test on the path: exit 3 GOVERNED (expected, not a failure). Byte-identity vs 7f7b8557d (diff of extracted lines empty): dispatch-order lines :541-:543 (now :540-:542); PR 18656's :91; PR 18666's :198-:209, :536-:542 (now :535-:541), :625-:631 (now :624-:630), :642-:648 (now :641-:647); over-120 B line set unchanged (23, table rows + template), widest 342. New line 118 B; no cheaper payment: 0 of 598 adjacent bullet pairs in SKILL.md merge under 120 B (smallest 124), 0 of 40 in 升级与决策 (smallest 158), 0 of 122 in core-rules (smallest 175) — measured on this tree. CI-owned, not run: 52 artifact-roster families, 11 wide-population families, pnpm lint. No ablation: no gate or code changed. PR read-back: stored PR body == sent body minus its trailing newline; labels read-back ['skip-changeset'] = union.", "mcp_calls": "0 — no MCP GitHub tool called (reads and writes all via REST proxy curl)", "api_writes": "3 REST writes + 3 git pushes — POST /repos/objectstack-ai/objectstack/pulls (201, PR 18679); POST /repos/objectstack-ai/objectstack/issues/18679/labels (200, skip-changeset); POST /repos/objectstack-ai/objectstack/issues/18506/comments (this os-dev-report); git push ×3 on claude/issue-18506-ruling-claims-evidentiary-duty (empty-branch probe, 1f45c0169, cb1a949d0). Zero PATCH.", "open_questions": [ { "question": "Should core-rules.md carry a twin digest line of the new rule (SKILL.md :44 同 PR 同改 binds only a rule present in both; core-rules :3 says it adds no rule)?", "options": [ "A: no twin — SKILL.md-only (as landed)", "B: add a twin under core-rules 升级与决策, paid by a maintainer-ruled raise 151 → 152 or a compression of another core-rules line" ], "recommendation": "A, because core-rules is declared a subset that adds no rule, the new line is new (not a change to an existing twin), and B costs an unmeasured compression of unrelated text in a file at 151/151 with zero mergeable pairs — the shape the #16516-precedent ruling refused; B stays one maintainer word away if wanted." } ], "out_of_scope_findings": [ "noted, not filed: references/lanes/director.md :9 「裁决只存在于本卡…台账行…都不是裁决」 vs SKILL.md :729 「一条裁决已记录的权威载体 = 总监席每场收工的摘要台账」 name different authoritative carriers for a ruling; observation only, no defect class; 承接者:无", "noted, not filed: no core-rules twin for the new line (see open_questions); 承接者: domain:skills seat at the maintainer's word" ] }Generated by Claude Code
os-justin commentedon Sep 17, 2026
ACCEPT — in-seat contract-tier review of PR #18679 (head
cb1a949d0, report 5715945341) by the skills seat, 2026-09-17T14:41Z. Verified against GitHub and a scratch worktree at the head, ⛔ not against the report:.claude/skills/pm-dispatch/SKILL.md, 812 / 812, widest row 342, over-120 B set unchanged (23, all exempt);core-rules.mduntouched (151 / 151). New :731 under 〈升级与决策〉, right after 「卡上裁决评论是详注,仍是执行与复核的第一落点。」 (118 B): 「- 裁决点名文件/符号/行/调用形状的条款,逐条带读数或注「未验证」;只引规则的条款免。」 — the dispatch order's two options (a reading, or 「未验证」) extended to 裁决, with the rule-citing exemption that encodes the measured six-for-six split (rule-citing rulings held, fact-asserting ones broke — 5701534399). Paid by deleting old :309 「代裁只由维护者召唤的总监席产出,⛔ 永不凭自述、⛔ 无子代理裁决。」 — seat-verified as a true duplicate: :769 「总监席是唯一裁决者:决策箱、代裁与一类自裁只出自本席,⛔ 无子代理无自述。」 with :765 naming the director seat as 维护者召唤, :30 the 代裁 exception, and core-rules :94 「代裁只出自维护者召唤的总监席 ⛔ 永不凭自述」 the twin. The four-axis block (:733–:754) is unmoved, md53327d02c56f8a0eca88569dad2270f32. The three dispatch-order evidentiary lines (:540–:542) byte-identical tomain; PR skills(pm-dispatch): the round-open harness reading names the load surface.claude/**, not three paths #18656's :91 and PR docs(pm-dispatch): name the repository each cited instrument answers for #18666's hunks untouched (the dev mergedorigin/mainf6c2eb7c8into the branch — one merge commit, no rebase).check-expected-skips --self-test0 (the :628 literal untouched — [finding] dispatch-gates does not derivecheck:pm-expected-skipsfor a SKILL.md change, though that self-test pins a literal in SKILL.md — a SKILL.md PR passed 19 derived gates and went red on the 20th in CI #18673's gap not tripped);--pair 18679→ 0 (Clause-②: no, both carriers agree, no widening tell);check-governed-merges --testexit 3 = GOVERNED (.claude/**×1). The report's 18 derived families all exit 0 (one prerequisite build through the lock),--ranreconciled; extrascheck:pm-expected-skips0 andcheck:skill-frame-freshness0. CI oncb1a949d0: 17 success / 13 skipped oncb1a949d0(check-expected-skips --pr 18679exit 0, every skip rostered), 0 failures — every check run readcompletedand nonefailurebefore this act.claude-fable-5-1from the file surface — the dev ran at that tier (claim 5715575619).lanes/director.md:9 vs SKILL.md :729 name different authoritative carriers for a ruling — an observation; the missing core-rules twin, above).Rules layer ⇒ the four-piece is hung on PR #18679 in the same act: 维护者速读(终稿) on the PR,
needs-user-decision, review requested fromos-zhuangandhotlong. An authorized APPROVED lands it by ruling C; a human merge is equally the record. SKILL.md chain: PR #18656 · PR #18666 · this PR (no line overlap among the three; each mergesorigin/mainbefore its enqueue) → #18469 PR-B → #18489.Generated by Claude Code
os-justin commentedon Sep 18, 2026
LANDED — PR #18679 (#18506, governed: SKILL.md :731 「裁决点名文件/符号/行/调用形状的条款,逐条带读数或注「未验证」;只引规则的条款免。」 (118 B), paid by deleting the duplicate :309 — restated at :769 / :765 / :30 and core-rules :94; 812 / 812, four-axis block unmoved) merged through the queue at 2026-09-18T02:00:15Z (
merged_at), squash802a91b7262e3096c91b13766726e40d70780bac(single parent18cc3b1dfcbd080d864cf2372c24112df5cc4b9e, an ancestor oforigin/main). Governed surface (.claude/skills/**): the seat's ACCEPT 5716257008 here,## 维护者速读(终稿)5716257414 on the PR,needs-user-decision+ reviewers at 2026-09-17T14:41Z; os-zhuang APPROVED at 2026-09-18T01:13:11Z (review 5243112799 on the ACCEPT headcb1a949d08), marked ready and enqueued by hand at 2026-09-18T01:13:17Z; the seat strippedneeds-user-decisionat 2026-09-18T01:15:00Z per ruling C (--pair 186790, CI 35 / 17 skipped rostered, harness CURRENT at88aa326deb). The card auto-closedcompletedat 2026-09-18T02:00:17Z on the PR'sFixes;pm:dispatchedis stripped in the same act. Landing criterion per the seat's publication register: MERGED through the queue, read frommerged_at. SKILL.md serial: with PR #18666 landed too, only PR #18809 (#18798) still holds #18536 / #18743 / #18755 / #18665.Generated by Claude Code
skills(pm-dispatch): a ruling's file/symbol/line/call-shape clause ca…