docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance - #14696

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes
Sep 2, 2026
Merged

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance#14696
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#14047

Lands the ruling's answer to the clause-② grading question in the ONE file the ruling names
as its 落点, and pays the line ratchet it crosses.

The ruling, verbatim and untranslated

Maintainer, 2026-09-01, comment 5494466874 (项目总监席 batch, maintainer's reply 逐字:「同意」):

裁决:(3) + (1) 的窄半 —— claim 声明按设计临时,真闸门在档位复审;新导出符号/新载荷键恒为 yes(维护者 2026-09-01,总监批 #23)

  1. (3) 获批:claim 时的 Clause-②: yes|no 声明按设计即临时(provisional) —— 它定派发档位的保守方向,⛔ 不是终审;真闸门在 PR/报告时的档位复审,证据与成本都在那里。声明被档位推翻不是席位过失,是机制按设计工作(本卡四标本中两例即如此);
  2. (1) 的窄半获批,作为机械地板:任何新导出符号或已发布载荷上的新键,恒为 yes —— claim 时可查树、无需判断,直接锁 fable 档;
  3. conformance 类(B/D 型)⛔ 不机械化:「向已声明面看齐 vs 收窄/加宽」的判别需要档位判断 —— 当天 validate-expressions has no flow leg for bare identifiers — a bare field reference in a flow condition passes objectstack validate clean #14089 即活标本(车道把 narrowing 读成 conformance 恢复,档位纠正)。裁定:claim 拿不准 ⇒ 按 yes 派 fable 档(地板的保守方向,假 yes 自纠、假 no 出货);
  4. (1) 全量分类学与 (2) 决策程序不建(创业镜头:现行机制四例四对,代价是复审轮不是出货缺陷);
  5. 落点:references/contract-review.md(受治面,skills 车道;若触行数天花板,按 [finding] The REST issues-list Link: rel="next" cursor silently returns 102 of 287 open issues — the dedup channel references/rest-channel.md prescribes #13900 裁决同型引用本评论提额)。⛔ 不重开四个标本 PR。

What landed — per item, 落点 | before | after

All three land as bullets in .claude/skills/pm-dispatch/references/contract-review.md,
in section 「载体纪律(挂与清)」, immediately after the 适用性 bullet — the file's existing
home for "what falls under clause ② and how it is graded". No new section: the ruling adds
grading rules to an applicability section that already exists.

#ruling item落点beforeafter
1claim declaration is provisional by design载体纪律, new bullet 「claim 声明按设计临时(provisional)」the file said nothing about the claim-time declaration at all — its first mention of Clause-② was as a place forward-looking facts liveClause-②: yes|no 只定派发档位的保守方向,⛔ 非终审;真闸门在 PR/报告时的档位复核 —— 证据与成本在那里。声明被档位推翻 = 机制按设计工作,⛔ 不作席位过失。」
2mechanical floor: new exported symbol / new published-payload key载体纪律, new bullet 「机械地板」, first limbabsent — the tier floor lived only in dispatch-gates.mjs --tier output, never in the review reference「任何新导出符号已发布载荷上的新键yes,直接锁契约复审档」, marked claim 时可查树、无需判断
3conformance class NOT mechanized; can't-tell dispatches as yessame bullet, second limbabsentconformance 类 ⛔ 不机械化(填充已声明字段、在两个已发布码之间重选输入类):判别需档位判断,claim 拿不准 ⇒ 按 yes 派契约复审档(假 yes 自纠、假 no 出货)」
4⛔ no full taxonomy, no decision proceduresame bullet, closing clauseabsent「⛔ 不建全量分类学与 claim 时决策程序(创业镜头:代价是复审轮)」

Ruling item 5 is the 落点 itself. Not done, deliberately: the four specimen PRs were not
reopened, and no file other than the reference (plus the ratchet's own CEILINGS row) is touched.

Provenance follows the file's own convention — 「维护者 2026-09-01「同意」」, by date and
quoted words. The file's header forbids issue ids (「⛔ 不引 issue 编号」) and
check:pm-skill-id-lint scans it against /#[0-9]{3,}/, so no card number appears in the
reference. The ruling's own authorizing sentence, which does carry an id, is quoted in the
CEILINGS map comment in scripts/pm/check-skill-line-ratchet.mjs — outside that gate's
SCAN_ROOT, which is .claude/skills/pm-dispatch only.

Line arithmetic

linesceilingheadroom
before60600
after payment (−2)58602
after the ruled addition (+7)65650

Payment came FIRST and it is real deleted bytes — not a re-wrap. 313 bytes went, and the
放行 bullet fell from 6 lines to 4.

Per-line 落点 of each deletion

  1. FAIL ⇒ 补丁轮;卡在决策 ⇒ 只进决策箱,⛔ 永不自裁 —— 真正设计分叉照旧升级维护者; (118 B)
    — restates SKILL.md 「条款②入队闸门」 almost phrase for phrase: 「FAIL ⇒ 补丁轮;⛔ 免复核不放行;
    真正设计分叉照旧进决策箱,席内复核 ⛔ 不替代维护者裁定」. Surviving anchor: SKILL.md, which
    this file's own header line 3 already points at — 「出处:主文件条款②闸门(原则/双肢与档位单源在彼)」.
    No rule is lost; the rule keeps its single source.
  2. **三样不变**:受管面照旧 draft-only + 终局两条(人工直合或授权批准钉 head 入队,单源见主文件)、⛔ 席位永不代批;FAIL / REWORK 原样;降档保险丝原样。 (195 B)
    — a self-declared restatement: it says 「单源见主文件」 in its own text. Surviving anchors, two:
    SKILL.md's ACCEPT 终局四件套 for the governed-surface limb, and — inside this same file —
    落地前检三条's 「受管面不适用,draft-only 终局不变」. Its remaining half (「FAIL / REWORK 原样;
    降档保险丝原样」) is a "nothing changed" statement carrying no rule, written when the in-seat
    rework landed; 降档保险丝 is the section directly below it.

Restatements measured and REJECTED as payment

A LINE ratchet cannot bank a deletion that does not cross a 120-byte boundary. These three are
real restatements, and deleting them buys nothing, so they were left alone rather than touched
for a number that would not move:

  • 停靠短暂(只防复核完成前误入队) in the 双载体 bullet — restates SKILL.md 「复核完成前短暂停靠」. −45 B, 3 lines → 3.
  • 非放行必要条件 in the 外部评审链 bullet — restates SKILL.md 「非放行前提」. −24 B, 4 lines → 4.
  • 可复审增量存在前永不挂标,提前挂已废止 in the 不预挂 bullet — restates SKILL.md 「随可复审契约增量同笔挂 … 前瞻预挂已废止(维护者 2026-08-28 裁定)」, same provenance date. −63 B, 2 lines → 2.

Why the residual +5 could not be paid

The ruled addition is 773 bytes of content. At the gate's own 120-byte cap that is 7 lines
minimum
(6 × 120 = 720 bytes, less than 773), so no six-line spelling exists that keeps the
ruled substance — and the last thing that would have to go is 「不是出货缺陷」, which is the
ruling's own stated justification for declining the taxonomy. Every landed line was checked
against the cap; the only over-120-byte lines in the file are the two legacy quotation-exempt
ruling quotes that were already there (122 B and 125 B), left exactly as their author broke them.

The raise is authorized by the ruling itself, verbatim and untranslated, from comment 5494466874:

若触行数天花板,按 #13900 裁决同型引用本评论提额

That sentence and its comment id are also quoted beside the row in the CEILINGS map, per the
map's standing convention. Ceiling set to the exact landed count, headroom 0.

Gates

Every one run through scripts/pm/os-verify-lock.sh, exit code captured by redirect BEFORE any
pipe, on committed head f999175 (working tree clean at the time of the run).

gateexitits own verdict line
check:pm-skill-ratchet0✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/contract-review.md is 65 lines (ceiling 65; headroom 0).
check:pm-skill-ratchet --self-test0✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint0✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g).
check:skill-frame-sync0✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
check:skill-frame-freshness0✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:pm-dispatch-gates0✓ dispatch-gates self-test: 1240 cases pass.
check:pm-governed-merges0✓ check-governed-merges --self-test: 241 assertions (…)
check:nul-bytes0check-nul-bytes: OK (scanned 8004 text file(s) -- 8004 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

Full union, re-derived AFTER the last edit

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, no hand-fed
paths, re-run on head f999175 and byte-identical to the pre-commit derivation. It resolved the
change set from git itself — 2 paths, committed 2 / working tree 0 — and named 20 commands.

15 of 20 measured, all exit 0: the 8 above plus check:agent-test-spelling,
check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs,
check:entry-guard, check:parse-guard, check:pnpm-filter-targets,
check:watch-hint-literal, scripts/check-cross-package-test-inputs.mjs,
scripts/pm/bare-root-worklist.mjs --self-test.

5 of 20 NOT MEASURED — never green, never a flake. Each exited 3 with its own PREREQUISITE
text (「Nothing was measured: this gate exited before running a single check」): the fresh
worktree has no node_modules, which these five need. They are
scripts/check-ci-filter-parity.mjs, scripts/check-shard-attestation.mjs,
scripts/check-test-completeness.mjs, pnpm --filter @objectstack/lint run check:doc-formula-expressions,
and pnpm check:doc-authoring. This is a declared narrowing:
the diff touches one .claude/** markdown file and one scripts/pm/ gate script, so none of the
five has an input in this change set, and CI runs the farm exactly once regardless.

Beyond the derived families: the diff edits a gate script, so that script's own suite was run
separately — check-skill-line-ratchet.mjs --self-test (111 cases, above). The repo carries no
*.test.ts naming it; the two other scripts that mention it
(check-skills-token-ratchet.mjs, check-published-list-mirrors.mjs) reference it only in prose
and were run anyway, both exit 0.

No changeset: this releases nothing. scripts/check-empty-changeset.mjs enumerates the class in
its own words — 「It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/,
tests-only, and the like)」 — and its guidance for that class is exactly this PR's shape: apply
the skip-changeset label instead. Governed surface (.claude/**), so this PR stays draft.

Follow-up, recorded not fixed

SKILL.md is deliberately untouched. One line in it reads in tension with 「provisional」 and is
worth the maintainer's eye — in 「条款②入队闸门」: 「错误的 no 是记录在案、可审计的假申报」.
Calling a wrong no a 假申报 frames the seat, while the ruling says a declaration overturned at
tier 「不是席位过失,是机制按设计工作」. The two are reconcilable — the ruling's 「不是席位过失」
is about being overturned at tier, and 假申报 is about the one direction that ships — but the
wording is the kind that gets read alone. Not edited here: the ruling names one 落点, and this
is not it.

premise_false

  • Retracted — this entry was wrong, and it was published before it was caught. This section
    first said the card carried no claim comment with this session's URL. It does: comment
    5514292041, 2026-09-02, session_01LraLgQVGq8egUwfYZpbYt1, branch
    claude/issue-14047-clause2-classes, declaring Clause-②: no. The false reading was a READ
    artifact, not a fact about the card — the issue page's SSR payload preloads only the first 15
    timeline items and the claim comment sits past that page, so "absent from the payload" was
    taken for "absent". A direct comment read settles it. The brief's premise held; the assignee
    (os-litant) and pm:dispatched / domain:skills / priority:p2 were correct as stated.
  • The brief pointed at a 「sibling gate defining token counts」 for skills/** diffs. It does not
    apply: this diff touches .claude/skills/**, and the ratchet's own header states the published
    skills/ catalog is deliberately OUTSIDE the ceiling — a different surface.
  • Channel: this session's GitHub gate is CLOSED. Every repo-scoped REST path answers 403
    (GitHub access is not enabled for this session), authenticated and not, and gh is absent.
    Card reads went through the zero-quota public-repo payload channel; writes through MCP.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Generated by Claude Code

…echanical floor, judged conformance
The clause-② criterion carried no grading rule, so seats produced three
materially different kinds of "yes" in a day and two conservative
declarations were overturned at tier. This lands the ruling's answer in
`references/contract-review.md`:
- the claim-time `Clause-②: yes|no` declaration is PROVISIONAL by design —
it fixes the conservative dispatch tier, and the real gate is the at-tier
review at PR/report time, where the evidence and the cost live; a
declaration overturned there is the mechanism working, not a seat fault;
- the mechanical floor: any NEW exported symbol, or any NEW key on an
already-published payload, is always `yes` — checkable in the tree at
claim time, no judgement — and it locks the contract-review tier;
- the conformance class is deliberately NOT mechanized (populating an
already-declared field, re-selecting an input class between two published
codes): it needs at-tier judgement, and a claim that cannot tell
dispatches as `yes` — a false `yes` self-corrects, a false `no` ships.
The full taxonomy and the claim-time decision procedure are both declined
under the startup-scope lens, and that refusal is itself ruled content.
Paid into the line ratchet first, in real deleted bytes and never a re-wrap:
the 放行 bullet's restated FAIL / 卡在决策 triple (single source is SKILL.md's
条款②入队闸门, which this file's header already points at) and the 三样不变
clause (self-declared 「单源见主文件」, its governed-surface limb surviving
in-file in 落地前检三条) went, taking that bullet from 6 lines to 4. The
residual +5 is the ruled addition at its reasoned floor; the ceiling moves
60 → 65 on the ruling's own authorization, quoted verbatim beside the row.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation labels Sep 2, 2026
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Sep 2, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 22:52
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 04798d9Sep 2, 2026
42 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14047-clause2-classes branch September 2, 2026 23:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance - #14696

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes
Sep 2, 2026
Merged

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance#14696
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#14047

Lands the ruling's answer to the clause-② grading question in the ONE file the ruling names
as its 落点, and pays the line ratchet it crosses.

The ruling, verbatim and untranslated

Maintainer, 2026-09-01, comment 5494466874 (项目总监席 batch, maintainer's reply 逐字:「同意」):

裁决:(3) + (1) 的窄半 —— claim 声明按设计临时,真闸门在档位复审;新导出符号/新载荷键恒为 yes(维护者 2026-09-01,总监批 #23)

  1. (3) 获批:claim 时的 Clause-②: yes|no 声明按设计即临时(provisional) —— 它定派发档位的保守方向,⛔ 不是终审;真闸门在 PR/报告时的档位复审,证据与成本都在那里。声明被档位推翻不是席位过失,是机制按设计工作(本卡四标本中两例即如此);
  2. (1) 的窄半获批,作为机械地板:任何新导出符号或已发布载荷上的新键,恒为 yes —— claim 时可查树、无需判断,直接锁 fable 档;
  3. conformance 类(B/D 型)⛔ 不机械化:「向已声明面看齐 vs 收窄/加宽」的判别需要档位判断 —— 当天 validate-expressions has no flow leg for bare identifiers — a bare field reference in a flow condition passes objectstack validate clean #14089 即活标本(车道把 narrowing 读成 conformance 恢复,档位纠正)。裁定:claim 拿不准 ⇒ 按 yes 派 fable 档(地板的保守方向,假 yes 自纠、假 no 出货);
  4. (1) 全量分类学与 (2) 决策程序不建(创业镜头:现行机制四例四对,代价是复审轮不是出货缺陷);
  5. 落点:references/contract-review.md(受治面,skills 车道;若触行数天花板,按 [finding] The REST issues-list Link: rel="next" cursor silently returns 102 of 287 open issues — the dedup channel references/rest-channel.md prescribes #13900 裁决同型引用本评论提额)。⛔ 不重开四个标本 PR。

What landed — per item, 落点 | before | after

All three land as bullets in .claude/skills/pm-dispatch/references/contract-review.md,
in section 「载体纪律(挂与清)」, immediately after the 适用性 bullet — the file's existing
home for "what falls under clause ② and how it is graded". No new section: the ruling adds
grading rules to an applicability section that already exists.

#ruling item落点beforeafter
1claim declaration is provisional by design载体纪律, new bullet 「claim 声明按设计临时(provisional)」the file said nothing about the claim-time declaration at all — its first mention of Clause-② was as a place forward-looking facts liveClause-②: yes|no 只定派发档位的保守方向,⛔ 非终审;真闸门在 PR/报告时的档位复核 —— 证据与成本在那里。声明被档位推翻 = 机制按设计工作,⛔ 不作席位过失。」
2mechanical floor: new exported symbol / new published-payload key载体纪律, new bullet 「机械地板」, first limbabsent — the tier floor lived only in dispatch-gates.mjs --tier output, never in the review reference「任何新导出符号已发布载荷上的新键yes,直接锁契约复审档」, marked claim 时可查树、无需判断
3conformance class NOT mechanized; can't-tell dispatches as yessame bullet, second limbabsentconformance 类 ⛔ 不机械化(填充已声明字段、在两个已发布码之间重选输入类):判别需档位判断,claim 拿不准 ⇒ 按 yes 派契约复审档(假 yes 自纠、假 no 出货)」
4⛔ no full taxonomy, no decision proceduresame bullet, closing clauseabsent「⛔ 不建全量分类学与 claim 时决策程序(创业镜头:代价是复审轮)」

Ruling item 5 is the 落点 itself. Not done, deliberately: the four specimen PRs were not
reopened, and no file other than the reference (plus the ratchet's own CEILINGS row) is touched.

Provenance follows the file's own convention — 「维护者 2026-09-01「同意」」, by date and
quoted words. The file's header forbids issue ids (「⛔ 不引 issue 编号」) and
check:pm-skill-id-lint scans it against /#[0-9]{3,}/, so no card number appears in the
reference. The ruling's own authorizing sentence, which does carry an id, is quoted in the
CEILINGS map comment in scripts/pm/check-skill-line-ratchet.mjs — outside that gate's
SCAN_ROOT, which is .claude/skills/pm-dispatch only.

Line arithmetic

linesceilingheadroom
before60600
after payment (−2)58602
after the ruled addition (+7)65650

Payment came FIRST and it is real deleted bytes — not a re-wrap. 313 bytes went, and the
放行 bullet fell from 6 lines to 4.

Per-line 落点 of each deletion

  1. FAIL ⇒ 补丁轮;卡在决策 ⇒ 只进决策箱,⛔ 永不自裁 —— 真正设计分叉照旧升级维护者; (118 B)
    — restates SKILL.md 「条款②入队闸门」 almost phrase for phrase: 「FAIL ⇒ 补丁轮;⛔ 免复核不放行;
    真正设计分叉照旧进决策箱,席内复核 ⛔ 不替代维护者裁定」. Surviving anchor: SKILL.md, which
    this file's own header line 3 already points at — 「出处:主文件条款②闸门(原则/双肢与档位单源在彼)」.
    No rule is lost; the rule keeps its single source.
  2. **三样不变**:受管面照旧 draft-only + 终局两条(人工直合或授权批准钉 head 入队,单源见主文件)、⛔ 席位永不代批;FAIL / REWORK 原样;降档保险丝原样。 (195 B)
    — a self-declared restatement: it says 「单源见主文件」 in its own text. Surviving anchors, two:
    SKILL.md's ACCEPT 终局四件套 for the governed-surface limb, and — inside this same file —
    落地前检三条's 「受管面不适用,draft-only 终局不变」. Its remaining half (「FAIL / REWORK 原样;
    降档保险丝原样」) is a "nothing changed" statement carrying no rule, written when the in-seat
    rework landed; 降档保险丝 is the section directly below it.

Restatements measured and REJECTED as payment

A LINE ratchet cannot bank a deletion that does not cross a 120-byte boundary. These three are
real restatements, and deleting them buys nothing, so they were left alone rather than touched
for a number that would not move:

  • 停靠短暂(只防复核完成前误入队) in the 双载体 bullet — restates SKILL.md 「复核完成前短暂停靠」. −45 B, 3 lines → 3.
  • 非放行必要条件 in the 外部评审链 bullet — restates SKILL.md 「非放行前提」. −24 B, 4 lines → 4.
  • 可复审增量存在前永不挂标,提前挂已废止 in the 不预挂 bullet — restates SKILL.md 「随可复审契约增量同笔挂 … 前瞻预挂已废止(维护者 2026-08-28 裁定)」, same provenance date. −63 B, 2 lines → 2.

Why the residual +5 could not be paid

The ruled addition is 773 bytes of content. At the gate's own 120-byte cap that is 7 lines
minimum
(6 × 120 = 720 bytes, less than 773), so no six-line spelling exists that keeps the
ruled substance — and the last thing that would have to go is 「不是出货缺陷」, which is the
ruling's own stated justification for declining the taxonomy. Every landed line was checked
against the cap; the only over-120-byte lines in the file are the two legacy quotation-exempt
ruling quotes that were already there (122 B and 125 B), left exactly as their author broke them.

The raise is authorized by the ruling itself, verbatim and untranslated, from comment 5494466874:

若触行数天花板,按 #13900 裁决同型引用本评论提额

That sentence and its comment id are also quoted beside the row in the CEILINGS map, per the
map's standing convention. Ceiling set to the exact landed count, headroom 0.

Gates

Every one run through scripts/pm/os-verify-lock.sh, exit code captured by redirect BEFORE any
pipe, on committed head f999175 (working tree clean at the time of the run).

gateexitits own verdict line
check:pm-skill-ratchet0✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/contract-review.md is 65 lines (ceiling 65; headroom 0).
check:pm-skill-ratchet --self-test0✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint0✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g).
check:skill-frame-sync0✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
check:skill-frame-freshness0✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:pm-dispatch-gates0✓ dispatch-gates self-test: 1240 cases pass.
check:pm-governed-merges0✓ check-governed-merges --self-test: 241 assertions (…)
check:nul-bytes0check-nul-bytes: OK (scanned 8004 text file(s) -- 8004 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

Full union, re-derived AFTER the last edit

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, no hand-fed
paths, re-run on head f999175 and byte-identical to the pre-commit derivation. It resolved the
change set from git itself — 2 paths, committed 2 / working tree 0 — and named 20 commands.

15 of 20 measured, all exit 0: the 8 above plus check:agent-test-spelling,
check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs,
check:entry-guard, check:parse-guard, check:pnpm-filter-targets,
check:watch-hint-literal, scripts/check-cross-package-test-inputs.mjs,
scripts/pm/bare-root-worklist.mjs --self-test.

5 of 20 NOT MEASURED — never green, never a flake. Each exited 3 with its own PREREQUISITE
text (「Nothing was measured: this gate exited before running a single check」): the fresh
worktree has no node_modules, which these five need. They are
scripts/check-ci-filter-parity.mjs, scripts/check-shard-attestation.mjs,
scripts/check-test-completeness.mjs, pnpm --filter @objectstack/lint run check:doc-formula-expressions,
and pnpm check:doc-authoring. This is a declared narrowing:
the diff touches one .claude/** markdown file and one scripts/pm/ gate script, so none of the
five has an input in this change set, and CI runs the farm exactly once regardless.

Beyond the derived families: the diff edits a gate script, so that script's own suite was run
separately — check-skill-line-ratchet.mjs --self-test (111 cases, above). The repo carries no
*.test.ts naming it; the two other scripts that mention it
(check-skills-token-ratchet.mjs, check-published-list-mirrors.mjs) reference it only in prose
and were run anyway, both exit 0.

No changeset: this releases nothing. scripts/check-empty-changeset.mjs enumerates the class in
its own words — 「It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/,
tests-only, and the like)」 — and its guidance for that class is exactly this PR's shape: apply
the skip-changeset label instead. Governed surface (.claude/**), so this PR stays draft.

Follow-up, recorded not fixed

SKILL.md is deliberately untouched. One line in it reads in tension with 「provisional」 and is
worth the maintainer's eye — in 「条款②入队闸门」: 「错误的 no 是记录在案、可审计的假申报」.
Calling a wrong no a 假申报 frames the seat, while the ruling says a declaration overturned at
tier 「不是席位过失,是机制按设计工作」. The two are reconcilable — the ruling's 「不是席位过失」
is about being overturned at tier, and 假申报 is about the one direction that ships — but the
wording is the kind that gets read alone. Not edited here: the ruling names one 落点, and this
is not it.

premise_false

  • Retracted — this entry was wrong, and it was published before it was caught. This section
    first said the card carried no claim comment with this session's URL. It does: comment
    5514292041, 2026-09-02, session_01LraLgQVGq8egUwfYZpbYt1, branch
    claude/issue-14047-clause2-classes, declaring Clause-②: no. The false reading was a READ
    artifact, not a fact about the card — the issue page's SSR payload preloads only the first 15
    timeline items and the claim comment sits past that page, so "absent from the payload" was
    taken for "absent". A direct comment read settles it. The brief's premise held; the assignee
    (os-litant) and pm:dispatched / domain:skills / priority:p2 were correct as stated.
  • The brief pointed at a 「sibling gate defining token counts」 for skills/** diffs. It does not
    apply: this diff touches .claude/skills/**, and the ratchet's own header states the published
    skills/ catalog is deliberately OUTSIDE the ceiling — a different surface.
  • Channel: this session's GitHub gate is CLOSED. Every repo-scoped REST path answers 403
    (GitHub access is not enabled for this session), authenticated and not, and gh is absent.
    Card reads went through the zero-quota public-repo payload channel; writes through MCP.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Generated by Claude Code

…echanical floor, judged conformance
The clause-② criterion carried no grading rule, so seats produced three
materially different kinds of "yes" in a day and two conservative
declarations were overturned at tier. This lands the ruling's answer in
`references/contract-review.md`:
- the claim-time `Clause-②: yes|no` declaration is PROVISIONAL by design —
it fixes the conservative dispatch tier, and the real gate is the at-tier
review at PR/report time, where the evidence and the cost live; a
declaration overturned there is the mechanism working, not a seat fault;
- the mechanical floor: any NEW exported symbol, or any NEW key on an
already-published payload, is always `yes` — checkable in the tree at
claim time, no judgement — and it locks the contract-review tier;
- the conformance class is deliberately NOT mechanized (populating an
already-declared field, re-selecting an input class between two published
codes): it needs at-tier judgement, and a claim that cannot tell
dispatches as `yes` — a false `yes` self-corrects, a false `no` ships.
The full taxonomy and the claim-time decision procedure are both declined
under the startup-scope lens, and that refusal is itself ruled content.
Paid into the line ratchet first, in real deleted bytes and never a re-wrap:
the 放行 bullet's restated FAIL / 卡在决策 triple (single source is SKILL.md's
条款②入队闸门, which this file's header already points at) and the 三样不变
clause (self-declared 「单源见主文件」, its governed-surface limb surviving
in-file in 落地前检三条) went, taking that bullet from 6 lines to 4. The
residual +5 is the ruled addition at its reasoned floor; the ceiling moves
60 → 65 on the ruling's own authorization, quoted verbatim beside the row.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation labels Sep 2, 2026
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Sep 2, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 22:52
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 04798d9Sep 2, 2026
42 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14047-clause2-classes branch September 2, 2026 23:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance - #14696

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes
Sep 2, 2026
Merged

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance#14696
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#14047

Lands the ruling's answer to the clause-② grading question in the ONE file the ruling names
as its 落点, and pays the line ratchet it crosses.

The ruling, verbatim and untranslated

Maintainer, 2026-09-01, comment 5494466874 (项目总监席 batch, maintainer's reply 逐字:「同意」):

裁决:(3) + (1) 的窄半 —— claim 声明按设计临时,真闸门在档位复审;新导出符号/新载荷键恒为 yes(维护者 2026-09-01,总监批 #23)

  1. (3) 获批:claim 时的 Clause-②: yes|no 声明按设计即临时(provisional) —— 它定派发档位的保守方向,⛔ 不是终审;真闸门在 PR/报告时的档位复审,证据与成本都在那里。声明被档位推翻不是席位过失,是机制按设计工作(本卡四标本中两例即如此);
  2. (1) 的窄半获批,作为机械地板:任何新导出符号或已发布载荷上的新键,恒为 yes —— claim 时可查树、无需判断,直接锁 fable 档;
  3. conformance 类(B/D 型)⛔ 不机械化:「向已声明面看齐 vs 收窄/加宽」的判别需要档位判断 —— 当天 validate-expressions has no flow leg for bare identifiers — a bare field reference in a flow condition passes objectstack validate clean #14089 即活标本(车道把 narrowing 读成 conformance 恢复,档位纠正)。裁定:claim 拿不准 ⇒ 按 yes 派 fable 档(地板的保守方向,假 yes 自纠、假 no 出货);
  4. (1) 全量分类学与 (2) 决策程序不建(创业镜头:现行机制四例四对,代价是复审轮不是出货缺陷);
  5. 落点:references/contract-review.md(受治面,skills 车道;若触行数天花板,按 [finding] The REST issues-list Link: rel="next" cursor silently returns 102 of 287 open issues — the dedup channel references/rest-channel.md prescribes #13900 裁决同型引用本评论提额)。⛔ 不重开四个标本 PR。

What landed — per item, 落点 | before | after

All three land as bullets in .claude/skills/pm-dispatch/references/contract-review.md,
in section 「载体纪律(挂与清)」, immediately after the 适用性 bullet — the file's existing
home for "what falls under clause ② and how it is graded". No new section: the ruling adds
grading rules to an applicability section that already exists.

#ruling item落点beforeafter
1claim declaration is provisional by design载体纪律, new bullet 「claim 声明按设计临时(provisional)」the file said nothing about the claim-time declaration at all — its first mention of Clause-② was as a place forward-looking facts liveClause-②: yes|no 只定派发档位的保守方向,⛔ 非终审;真闸门在 PR/报告时的档位复核 —— 证据与成本在那里。声明被档位推翻 = 机制按设计工作,⛔ 不作席位过失。」
2mechanical floor: new exported symbol / new published-payload key载体纪律, new bullet 「机械地板」, first limbabsent — the tier floor lived only in dispatch-gates.mjs --tier output, never in the review reference「任何新导出符号已发布载荷上的新键yes,直接锁契约复审档」, marked claim 时可查树、无需判断
3conformance class NOT mechanized; can't-tell dispatches as yessame bullet, second limbabsentconformance 类 ⛔ 不机械化(填充已声明字段、在两个已发布码之间重选输入类):判别需档位判断,claim 拿不准 ⇒ 按 yes 派契约复审档(假 yes 自纠、假 no 出货)」
4⛔ no full taxonomy, no decision proceduresame bullet, closing clauseabsent「⛔ 不建全量分类学与 claim 时决策程序(创业镜头:代价是复审轮)」

Ruling item 5 is the 落点 itself. Not done, deliberately: the four specimen PRs were not
reopened, and no file other than the reference (plus the ratchet's own CEILINGS row) is touched.

Provenance follows the file's own convention — 「维护者 2026-09-01「同意」」, by date and
quoted words. The file's header forbids issue ids (「⛔ 不引 issue 编号」) and
check:pm-skill-id-lint scans it against /#[0-9]{3,}/, so no card number appears in the
reference. The ruling's own authorizing sentence, which does carry an id, is quoted in the
CEILINGS map comment in scripts/pm/check-skill-line-ratchet.mjs — outside that gate's
SCAN_ROOT, which is .claude/skills/pm-dispatch only.

Line arithmetic

linesceilingheadroom
before60600
after payment (−2)58602
after the ruled addition (+7)65650

Payment came FIRST and it is real deleted bytes — not a re-wrap. 313 bytes went, and the
放行 bullet fell from 6 lines to 4.

Per-line 落点 of each deletion

  1. FAIL ⇒ 补丁轮;卡在决策 ⇒ 只进决策箱,⛔ 永不自裁 —— 真正设计分叉照旧升级维护者; (118 B)
    — restates SKILL.md 「条款②入队闸门」 almost phrase for phrase: 「FAIL ⇒ 补丁轮;⛔ 免复核不放行;
    真正设计分叉照旧进决策箱,席内复核 ⛔ 不替代维护者裁定」. Surviving anchor: SKILL.md, which
    this file's own header line 3 already points at — 「出处:主文件条款②闸门(原则/双肢与档位单源在彼)」.
    No rule is lost; the rule keeps its single source.
  2. **三样不变**:受管面照旧 draft-only + 终局两条(人工直合或授权批准钉 head 入队,单源见主文件)、⛔ 席位永不代批;FAIL / REWORK 原样;降档保险丝原样。 (195 B)
    — a self-declared restatement: it says 「单源见主文件」 in its own text. Surviving anchors, two:
    SKILL.md's ACCEPT 终局四件套 for the governed-surface limb, and — inside this same file —
    落地前检三条's 「受管面不适用,draft-only 终局不变」. Its remaining half (「FAIL / REWORK 原样;
    降档保险丝原样」) is a "nothing changed" statement carrying no rule, written when the in-seat
    rework landed; 降档保险丝 is the section directly below it.

Restatements measured and REJECTED as payment

A LINE ratchet cannot bank a deletion that does not cross a 120-byte boundary. These three are
real restatements, and deleting them buys nothing, so they were left alone rather than touched
for a number that would not move:

  • 停靠短暂(只防复核完成前误入队) in the 双载体 bullet — restates SKILL.md 「复核完成前短暂停靠」. −45 B, 3 lines → 3.
  • 非放行必要条件 in the 外部评审链 bullet — restates SKILL.md 「非放行前提」. −24 B, 4 lines → 4.
  • 可复审增量存在前永不挂标,提前挂已废止 in the 不预挂 bullet — restates SKILL.md 「随可复审契约增量同笔挂 … 前瞻预挂已废止(维护者 2026-08-28 裁定)」, same provenance date. −63 B, 2 lines → 2.

Why the residual +5 could not be paid

The ruled addition is 773 bytes of content. At the gate's own 120-byte cap that is 7 lines
minimum
(6 × 120 = 720 bytes, less than 773), so no six-line spelling exists that keeps the
ruled substance — and the last thing that would have to go is 「不是出货缺陷」, which is the
ruling's own stated justification for declining the taxonomy. Every landed line was checked
against the cap; the only over-120-byte lines in the file are the two legacy quotation-exempt
ruling quotes that were already there (122 B and 125 B), left exactly as their author broke them.

The raise is authorized by the ruling itself, verbatim and untranslated, from comment 5494466874:

若触行数天花板,按 #13900 裁决同型引用本评论提额

That sentence and its comment id are also quoted beside the row in the CEILINGS map, per the
map's standing convention. Ceiling set to the exact landed count, headroom 0.

Gates

Every one run through scripts/pm/os-verify-lock.sh, exit code captured by redirect BEFORE any
pipe, on committed head f999175 (working tree clean at the time of the run).

gateexitits own verdict line
check:pm-skill-ratchet0✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/contract-review.md is 65 lines (ceiling 65; headroom 0).
check:pm-skill-ratchet --self-test0✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint0✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g).
check:skill-frame-sync0✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
check:skill-frame-freshness0✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:pm-dispatch-gates0✓ dispatch-gates self-test: 1240 cases pass.
check:pm-governed-merges0✓ check-governed-merges --self-test: 241 assertions (…)
check:nul-bytes0check-nul-bytes: OK (scanned 8004 text file(s) -- 8004 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

Full union, re-derived AFTER the last edit

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, no hand-fed
paths, re-run on head f999175 and byte-identical to the pre-commit derivation. It resolved the
change set from git itself — 2 paths, committed 2 / working tree 0 — and named 20 commands.

15 of 20 measured, all exit 0: the 8 above plus check:agent-test-spelling,
check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs,
check:entry-guard, check:parse-guard, check:pnpm-filter-targets,
check:watch-hint-literal, scripts/check-cross-package-test-inputs.mjs,
scripts/pm/bare-root-worklist.mjs --self-test.

5 of 20 NOT MEASURED — never green, never a flake. Each exited 3 with its own PREREQUISITE
text (「Nothing was measured: this gate exited before running a single check」): the fresh
worktree has no node_modules, which these five need. They are
scripts/check-ci-filter-parity.mjs, scripts/check-shard-attestation.mjs,
scripts/check-test-completeness.mjs, pnpm --filter @objectstack/lint run check:doc-formula-expressions,
and pnpm check:doc-authoring. This is a declared narrowing:
the diff touches one .claude/** markdown file and one scripts/pm/ gate script, so none of the
five has an input in this change set, and CI runs the farm exactly once regardless.

Beyond the derived families: the diff edits a gate script, so that script's own suite was run
separately — check-skill-line-ratchet.mjs --self-test (111 cases, above). The repo carries no
*.test.ts naming it; the two other scripts that mention it
(check-skills-token-ratchet.mjs, check-published-list-mirrors.mjs) reference it only in prose
and were run anyway, both exit 0.

No changeset: this releases nothing. scripts/check-empty-changeset.mjs enumerates the class in
its own words — 「It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/,
tests-only, and the like)」 — and its guidance for that class is exactly this PR's shape: apply
the skip-changeset label instead. Governed surface (.claude/**), so this PR stays draft.

Follow-up, recorded not fixed

SKILL.md is deliberately untouched. One line in it reads in tension with 「provisional」 and is
worth the maintainer's eye — in 「条款②入队闸门」: 「错误的 no 是记录在案、可审计的假申报」.
Calling a wrong no a 假申报 frames the seat, while the ruling says a declaration overturned at
tier 「不是席位过失,是机制按设计工作」. The two are reconcilable — the ruling's 「不是席位过失」
is about being overturned at tier, and 假申报 is about the one direction that ships — but the
wording is the kind that gets read alone. Not edited here: the ruling names one 落点, and this
is not it.

premise_false

  • Retracted — this entry was wrong, and it was published before it was caught. This section
    first said the card carried no claim comment with this session's URL. It does: comment
    5514292041, 2026-09-02, session_01LraLgQVGq8egUwfYZpbYt1, branch
    claude/issue-14047-clause2-classes, declaring Clause-②: no. The false reading was a READ
    artifact, not a fact about the card — the issue page's SSR payload preloads only the first 15
    timeline items and the claim comment sits past that page, so "absent from the payload" was
    taken for "absent". A direct comment read settles it. The brief's premise held; the assignee
    (os-litant) and pm:dispatched / domain:skills / priority:p2 were correct as stated.
  • The brief pointed at a 「sibling gate defining token counts」 for skills/** diffs. It does not
    apply: this diff touches .claude/skills/**, and the ratchet's own header states the published
    skills/ catalog is deliberately OUTSIDE the ceiling — a different surface.
  • Channel: this session's GitHub gate is CLOSED. Every repo-scoped REST path answers 403
    (GitHub access is not enabled for this session), authenticated and not, and gh is absent.
    Card reads went through the zero-quota public-repo payload channel; writes through MCP.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Generated by Claude Code

…echanical floor, judged conformance
The clause-② criterion carried no grading rule, so seats produced three
materially different kinds of "yes" in a day and two conservative
declarations were overturned at tier. This lands the ruling's answer in
`references/contract-review.md`:
- the claim-time `Clause-②: yes|no` declaration is PROVISIONAL by design —
it fixes the conservative dispatch tier, and the real gate is the at-tier
review at PR/report time, where the evidence and the cost live; a
declaration overturned there is the mechanism working, not a seat fault;
- the mechanical floor: any NEW exported symbol, or any NEW key on an
already-published payload, is always `yes` — checkable in the tree at
claim time, no judgement — and it locks the contract-review tier;
- the conformance class is deliberately NOT mechanized (populating an
already-declared field, re-selecting an input class between two published
codes): it needs at-tier judgement, and a claim that cannot tell
dispatches as `yes` — a false `yes` self-corrects, a false `no` ships.
The full taxonomy and the claim-time decision procedure are both declined
under the startup-scope lens, and that refusal is itself ruled content.
Paid into the line ratchet first, in real deleted bytes and never a re-wrap:
the 放行 bullet's restated FAIL / 卡在决策 triple (single source is SKILL.md's
条款②入队闸门, which this file's header already points at) and the 三样不变
clause (self-declared 「单源见主文件」, its governed-surface limb surviving
in-file in 落地前检三条) went, taking that bullet from 6 lines to 4. The
residual +5 is the ruled addition at its reasoned floor; the ceiling moves
60 → 65 on the ruling's own authorization, quoted verbatim beside the row.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation labels Sep 2, 2026
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Sep 2, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 22:52
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 04798d9Sep 2, 2026
42 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14047-clause2-classes branch September 2, 2026 23:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance - #14696

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes
Sep 2, 2026
Merged

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance#14696
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#14047

Lands the ruling's answer to the clause-② grading question in the ONE file the ruling names
as its 落点, and pays the line ratchet it crosses.

The ruling, verbatim and untranslated

Maintainer, 2026-09-01, comment 5494466874 (项目总监席 batch, maintainer's reply 逐字:「同意」):

裁决:(3) + (1) 的窄半 —— claim 声明按设计临时,真闸门在档位复审;新导出符号/新载荷键恒为 yes(维护者 2026-09-01,总监批 #23)

  1. (3) 获批:claim 时的 Clause-②: yes|no 声明按设计即临时(provisional) —— 它定派发档位的保守方向,⛔ 不是终审;真闸门在 PR/报告时的档位复审,证据与成本都在那里。声明被档位推翻不是席位过失,是机制按设计工作(本卡四标本中两例即如此);
  2. (1) 的窄半获批,作为机械地板:任何新导出符号或已发布载荷上的新键,恒为 yes —— claim 时可查树、无需判断,直接锁 fable 档;
  3. conformance 类(B/D 型)⛔ 不机械化:「向已声明面看齐 vs 收窄/加宽」的判别需要档位判断 —— 当天 validate-expressions has no flow leg for bare identifiers — a bare field reference in a flow condition passes objectstack validate clean #14089 即活标本(车道把 narrowing 读成 conformance 恢复,档位纠正)。裁定:claim 拿不准 ⇒ 按 yes 派 fable 档(地板的保守方向,假 yes 自纠、假 no 出货);
  4. (1) 全量分类学与 (2) 决策程序不建(创业镜头:现行机制四例四对,代价是复审轮不是出货缺陷);
  5. 落点:references/contract-review.md(受治面,skills 车道;若触行数天花板,按 [finding] The REST issues-list Link: rel="next" cursor silently returns 102 of 287 open issues — the dedup channel references/rest-channel.md prescribes #13900 裁决同型引用本评论提额)。⛔ 不重开四个标本 PR。

What landed — per item, 落点 | before | after

All three land as bullets in .claude/skills/pm-dispatch/references/contract-review.md,
in section 「载体纪律(挂与清)」, immediately after the 适用性 bullet — the file's existing
home for "what falls under clause ② and how it is graded". No new section: the ruling adds
grading rules to an applicability section that already exists.

#ruling item落点beforeafter
1claim declaration is provisional by design载体纪律, new bullet 「claim 声明按设计临时(provisional)」the file said nothing about the claim-time declaration at all — its first mention of Clause-② was as a place forward-looking facts liveClause-②: yes|no 只定派发档位的保守方向,⛔ 非终审;真闸门在 PR/报告时的档位复核 —— 证据与成本在那里。声明被档位推翻 = 机制按设计工作,⛔ 不作席位过失。」
2mechanical floor: new exported symbol / new published-payload key载体纪律, new bullet 「机械地板」, first limbabsent — the tier floor lived only in dispatch-gates.mjs --tier output, never in the review reference「任何新导出符号已发布载荷上的新键yes,直接锁契约复审档」, marked claim 时可查树、无需判断
3conformance class NOT mechanized; can't-tell dispatches as yessame bullet, second limbabsentconformance 类 ⛔ 不机械化(填充已声明字段、在两个已发布码之间重选输入类):判别需档位判断,claim 拿不准 ⇒ 按 yes 派契约复审档(假 yes 自纠、假 no 出货)」
4⛔ no full taxonomy, no decision proceduresame bullet, closing clauseabsent「⛔ 不建全量分类学与 claim 时决策程序(创业镜头:代价是复审轮)」

Ruling item 5 is the 落点 itself. Not done, deliberately: the four specimen PRs were not
reopened, and no file other than the reference (plus the ratchet's own CEILINGS row) is touched.

Provenance follows the file's own convention — 「维护者 2026-09-01「同意」」, by date and
quoted words. The file's header forbids issue ids (「⛔ 不引 issue 编号」) and
check:pm-skill-id-lint scans it against /#[0-9]{3,}/, so no card number appears in the
reference. The ruling's own authorizing sentence, which does carry an id, is quoted in the
CEILINGS map comment in scripts/pm/check-skill-line-ratchet.mjs — outside that gate's
SCAN_ROOT, which is .claude/skills/pm-dispatch only.

Line arithmetic

linesceilingheadroom
before60600
after payment (−2)58602
after the ruled addition (+7)65650

Payment came FIRST and it is real deleted bytes — not a re-wrap. 313 bytes went, and the
放行 bullet fell from 6 lines to 4.

Per-line 落点 of each deletion

  1. FAIL ⇒ 补丁轮;卡在决策 ⇒ 只进决策箱,⛔ 永不自裁 —— 真正设计分叉照旧升级维护者; (118 B)
    — restates SKILL.md 「条款②入队闸门」 almost phrase for phrase: 「FAIL ⇒ 补丁轮;⛔ 免复核不放行;
    真正设计分叉照旧进决策箱,席内复核 ⛔ 不替代维护者裁定」. Surviving anchor: SKILL.md, which
    this file's own header line 3 already points at — 「出处:主文件条款②闸门(原则/双肢与档位单源在彼)」.
    No rule is lost; the rule keeps its single source.
  2. **三样不变**:受管面照旧 draft-only + 终局两条(人工直合或授权批准钉 head 入队,单源见主文件)、⛔ 席位永不代批;FAIL / REWORK 原样;降档保险丝原样。 (195 B)
    — a self-declared restatement: it says 「单源见主文件」 in its own text. Surviving anchors, two:
    SKILL.md's ACCEPT 终局四件套 for the governed-surface limb, and — inside this same file —
    落地前检三条's 「受管面不适用,draft-only 终局不变」. Its remaining half (「FAIL / REWORK 原样;
    降档保险丝原样」) is a "nothing changed" statement carrying no rule, written when the in-seat
    rework landed; 降档保险丝 is the section directly below it.

Restatements measured and REJECTED as payment

A LINE ratchet cannot bank a deletion that does not cross a 120-byte boundary. These three are
real restatements, and deleting them buys nothing, so they were left alone rather than touched
for a number that would not move:

  • 停靠短暂(只防复核完成前误入队) in the 双载体 bullet — restates SKILL.md 「复核完成前短暂停靠」. −45 B, 3 lines → 3.
  • 非放行必要条件 in the 外部评审链 bullet — restates SKILL.md 「非放行前提」. −24 B, 4 lines → 4.
  • 可复审增量存在前永不挂标,提前挂已废止 in the 不预挂 bullet — restates SKILL.md 「随可复审契约增量同笔挂 … 前瞻预挂已废止(维护者 2026-08-28 裁定)」, same provenance date. −63 B, 2 lines → 2.

Why the residual +5 could not be paid

The ruled addition is 773 bytes of content. At the gate's own 120-byte cap that is 7 lines
minimum
(6 × 120 = 720 bytes, less than 773), so no six-line spelling exists that keeps the
ruled substance — and the last thing that would have to go is 「不是出货缺陷」, which is the
ruling's own stated justification for declining the taxonomy. Every landed line was checked
against the cap; the only over-120-byte lines in the file are the two legacy quotation-exempt
ruling quotes that were already there (122 B and 125 B), left exactly as their author broke them.

The raise is authorized by the ruling itself, verbatim and untranslated, from comment 5494466874:

若触行数天花板,按 #13900 裁决同型引用本评论提额

That sentence and its comment id are also quoted beside the row in the CEILINGS map, per the
map's standing convention. Ceiling set to the exact landed count, headroom 0.

Gates

Every one run through scripts/pm/os-verify-lock.sh, exit code captured by redirect BEFORE any
pipe, on committed head f999175 (working tree clean at the time of the run).

gateexitits own verdict line
check:pm-skill-ratchet0✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/contract-review.md is 65 lines (ceiling 65; headroom 0).
check:pm-skill-ratchet --self-test0✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint0✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g).
check:skill-frame-sync0✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
check:skill-frame-freshness0✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:pm-dispatch-gates0✓ dispatch-gates self-test: 1240 cases pass.
check:pm-governed-merges0✓ check-governed-merges --self-test: 241 assertions (…)
check:nul-bytes0check-nul-bytes: OK (scanned 8004 text file(s) -- 8004 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

Full union, re-derived AFTER the last edit

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, no hand-fed
paths, re-run on head f999175 and byte-identical to the pre-commit derivation. It resolved the
change set from git itself — 2 paths, committed 2 / working tree 0 — and named 20 commands.

15 of 20 measured, all exit 0: the 8 above plus check:agent-test-spelling,
check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs,
check:entry-guard, check:parse-guard, check:pnpm-filter-targets,
check:watch-hint-literal, scripts/check-cross-package-test-inputs.mjs,
scripts/pm/bare-root-worklist.mjs --self-test.

5 of 20 NOT MEASURED — never green, never a flake. Each exited 3 with its own PREREQUISITE
text (「Nothing was measured: this gate exited before running a single check」): the fresh
worktree has no node_modules, which these five need. They are
scripts/check-ci-filter-parity.mjs, scripts/check-shard-attestation.mjs,
scripts/check-test-completeness.mjs, pnpm --filter @objectstack/lint run check:doc-formula-expressions,
and pnpm check:doc-authoring. This is a declared narrowing:
the diff touches one .claude/** markdown file and one scripts/pm/ gate script, so none of the
five has an input in this change set, and CI runs the farm exactly once regardless.

Beyond the derived families: the diff edits a gate script, so that script's own suite was run
separately — check-skill-line-ratchet.mjs --self-test (111 cases, above). The repo carries no
*.test.ts naming it; the two other scripts that mention it
(check-skills-token-ratchet.mjs, check-published-list-mirrors.mjs) reference it only in prose
and were run anyway, both exit 0.

No changeset: this releases nothing. scripts/check-empty-changeset.mjs enumerates the class in
its own words — 「It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/,
tests-only, and the like)」 — and its guidance for that class is exactly this PR's shape: apply
the skip-changeset label instead. Governed surface (.claude/**), so this PR stays draft.

Follow-up, recorded not fixed

SKILL.md is deliberately untouched. One line in it reads in tension with 「provisional」 and is
worth the maintainer's eye — in 「条款②入队闸门」: 「错误的 no 是记录在案、可审计的假申报」.
Calling a wrong no a 假申报 frames the seat, while the ruling says a declaration overturned at
tier 「不是席位过失,是机制按设计工作」. The two are reconcilable — the ruling's 「不是席位过失」
is about being overturned at tier, and 假申报 is about the one direction that ships — but the
wording is the kind that gets read alone. Not edited here: the ruling names one 落点, and this
is not it.

premise_false

  • Retracted — this entry was wrong, and it was published before it was caught. This section
    first said the card carried no claim comment with this session's URL. It does: comment
    5514292041, 2026-09-02, session_01LraLgQVGq8egUwfYZpbYt1, branch
    claude/issue-14047-clause2-classes, declaring Clause-②: no. The false reading was a READ
    artifact, not a fact about the card — the issue page's SSR payload preloads only the first 15
    timeline items and the claim comment sits past that page, so "absent from the payload" was
    taken for "absent". A direct comment read settles it. The brief's premise held; the assignee
    (os-litant) and pm:dispatched / domain:skills / priority:p2 were correct as stated.
  • The brief pointed at a 「sibling gate defining token counts」 for skills/** diffs. It does not
    apply: this diff touches .claude/skills/**, and the ratchet's own header states the published
    skills/ catalog is deliberately OUTSIDE the ceiling — a different surface.
  • Channel: this session's GitHub gate is CLOSED. Every repo-scoped REST path answers 403
    (GitHub access is not enabled for this session), authenticated and not, and gh is absent.
    Card reads went through the zero-quota public-repo payload channel; writes through MCP.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Generated by Claude Code

…echanical floor, judged conformance
The clause-② criterion carried no grading rule, so seats produced three
materially different kinds of "yes" in a day and two conservative
declarations were overturned at tier. This lands the ruling's answer in
`references/contract-review.md`:
- the claim-time `Clause-②: yes|no` declaration is PROVISIONAL by design —
it fixes the conservative dispatch tier, and the real gate is the at-tier
review at PR/report time, where the evidence and the cost live; a
declaration overturned there is the mechanism working, not a seat fault;
- the mechanical floor: any NEW exported symbol, or any NEW key on an
already-published payload, is always `yes` — checkable in the tree at
claim time, no judgement — and it locks the contract-review tier;
- the conformance class is deliberately NOT mechanized (populating an
already-declared field, re-selecting an input class between two published
codes): it needs at-tier judgement, and a claim that cannot tell
dispatches as `yes` — a false `yes` self-corrects, a false `no` ships.
The full taxonomy and the claim-time decision procedure are both declined
under the startup-scope lens, and that refusal is itself ruled content.
Paid into the line ratchet first, in real deleted bytes and never a re-wrap:
the 放行 bullet's restated FAIL / 卡在决策 triple (single source is SKILL.md's
条款②入队闸门, which this file's header already points at) and the 三样不变
clause (self-declared 「单源见主文件」, its governed-surface limb surviving
in-file in 落地前检三条) went, taking that bullet from 6 lines to 4. The
residual +5 is the ruled addition at its reasoned floor; the ceiling moves
60 → 65 on the ruling's own authorization, quoted verbatim beside the row.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation labels Sep 2, 2026
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Sep 2, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 22:52
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 04798d9Sep 2, 2026
42 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14047-clause2-classes branch September 2, 2026 23:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance - #14696

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes
Sep 2, 2026
Merged

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance#14696
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#14047

Lands the ruling's answer to the clause-② grading question in the ONE file the ruling names
as its 落点, and pays the line ratchet it crosses.

The ruling, verbatim and untranslated

Maintainer, 2026-09-01, comment 5494466874 (项目总监席 batch, maintainer's reply 逐字:「同意」):

裁决:(3) + (1) 的窄半 —— claim 声明按设计临时,真闸门在档位复审;新导出符号/新载荷键恒为 yes(维护者 2026-09-01,总监批 #23)

  1. (3) 获批:claim 时的 Clause-②: yes|no 声明按设计即临时(provisional) —— 它定派发档位的保守方向,⛔ 不是终审;真闸门在 PR/报告时的档位复审,证据与成本都在那里。声明被档位推翻不是席位过失,是机制按设计工作(本卡四标本中两例即如此);
  2. (1) 的窄半获批,作为机械地板:任何新导出符号或已发布载荷上的新键,恒为 yes —— claim 时可查树、无需判断,直接锁 fable 档;
  3. conformance 类(B/D 型)⛔ 不机械化:「向已声明面看齐 vs 收窄/加宽」的判别需要档位判断 —— 当天 validate-expressions has no flow leg for bare identifiers — a bare field reference in a flow condition passes objectstack validate clean #14089 即活标本(车道把 narrowing 读成 conformance 恢复,档位纠正)。裁定:claim 拿不准 ⇒ 按 yes 派 fable 档(地板的保守方向,假 yes 自纠、假 no 出货);
  4. (1) 全量分类学与 (2) 决策程序不建(创业镜头:现行机制四例四对,代价是复审轮不是出货缺陷);
  5. 落点:references/contract-review.md(受治面,skills 车道;若触行数天花板,按 [finding] The REST issues-list Link: rel="next" cursor silently returns 102 of 287 open issues — the dedup channel references/rest-channel.md prescribes #13900 裁决同型引用本评论提额)。⛔ 不重开四个标本 PR。

What landed — per item, 落点 | before | after

All three land as bullets in .claude/skills/pm-dispatch/references/contract-review.md,
in section 「载体纪律(挂与清)」, immediately after the 适用性 bullet — the file's existing
home for "what falls under clause ② and how it is graded". No new section: the ruling adds
grading rules to an applicability section that already exists.

#ruling item落点beforeafter
1claim declaration is provisional by design载体纪律, new bullet 「claim 声明按设计临时(provisional)」the file said nothing about the claim-time declaration at all — its first mention of Clause-② was as a place forward-looking facts liveClause-②: yes|no 只定派发档位的保守方向,⛔ 非终审;真闸门在 PR/报告时的档位复核 —— 证据与成本在那里。声明被档位推翻 = 机制按设计工作,⛔ 不作席位过失。」
2mechanical floor: new exported symbol / new published-payload key载体纪律, new bullet 「机械地板」, first limbabsent — the tier floor lived only in dispatch-gates.mjs --tier output, never in the review reference「任何新导出符号已发布载荷上的新键yes,直接锁契约复审档」, marked claim 时可查树、无需判断
3conformance class NOT mechanized; can't-tell dispatches as yessame bullet, second limbabsentconformance 类 ⛔ 不机械化(填充已声明字段、在两个已发布码之间重选输入类):判别需档位判断,claim 拿不准 ⇒ 按 yes 派契约复审档(假 yes 自纠、假 no 出货)」
4⛔ no full taxonomy, no decision proceduresame bullet, closing clauseabsent「⛔ 不建全量分类学与 claim 时决策程序(创业镜头:代价是复审轮)」

Ruling item 5 is the 落点 itself. Not done, deliberately: the four specimen PRs were not
reopened, and no file other than the reference (plus the ratchet's own CEILINGS row) is touched.

Provenance follows the file's own convention — 「维护者 2026-09-01「同意」」, by date and
quoted words. The file's header forbids issue ids (「⛔ 不引 issue 编号」) and
check:pm-skill-id-lint scans it against /#[0-9]{3,}/, so no card number appears in the
reference. The ruling's own authorizing sentence, which does carry an id, is quoted in the
CEILINGS map comment in scripts/pm/check-skill-line-ratchet.mjs — outside that gate's
SCAN_ROOT, which is .claude/skills/pm-dispatch only.

Line arithmetic

linesceilingheadroom
before60600
after payment (−2)58602
after the ruled addition (+7)65650

Payment came FIRST and it is real deleted bytes — not a re-wrap. 313 bytes went, and the
放行 bullet fell from 6 lines to 4.

Per-line 落点 of each deletion

  1. FAIL ⇒ 补丁轮;卡在决策 ⇒ 只进决策箱,⛔ 永不自裁 —— 真正设计分叉照旧升级维护者; (118 B)
    — restates SKILL.md 「条款②入队闸门」 almost phrase for phrase: 「FAIL ⇒ 补丁轮;⛔ 免复核不放行;
    真正设计分叉照旧进决策箱,席内复核 ⛔ 不替代维护者裁定」. Surviving anchor: SKILL.md, which
    this file's own header line 3 already points at — 「出处:主文件条款②闸门(原则/双肢与档位单源在彼)」.
    No rule is lost; the rule keeps its single source.
  2. **三样不变**:受管面照旧 draft-only + 终局两条(人工直合或授权批准钉 head 入队,单源见主文件)、⛔ 席位永不代批;FAIL / REWORK 原样;降档保险丝原样。 (195 B)
    — a self-declared restatement: it says 「单源见主文件」 in its own text. Surviving anchors, two:
    SKILL.md's ACCEPT 终局四件套 for the governed-surface limb, and — inside this same file —
    落地前检三条's 「受管面不适用,draft-only 终局不变」. Its remaining half (「FAIL / REWORK 原样;
    降档保险丝原样」) is a "nothing changed" statement carrying no rule, written when the in-seat
    rework landed; 降档保险丝 is the section directly below it.

Restatements measured and REJECTED as payment

A LINE ratchet cannot bank a deletion that does not cross a 120-byte boundary. These three are
real restatements, and deleting them buys nothing, so they were left alone rather than touched
for a number that would not move:

  • 停靠短暂(只防复核完成前误入队) in the 双载体 bullet — restates SKILL.md 「复核完成前短暂停靠」. −45 B, 3 lines → 3.
  • 非放行必要条件 in the 外部评审链 bullet — restates SKILL.md 「非放行前提」. −24 B, 4 lines → 4.
  • 可复审增量存在前永不挂标,提前挂已废止 in the 不预挂 bullet — restates SKILL.md 「随可复审契约增量同笔挂 … 前瞻预挂已废止(维护者 2026-08-28 裁定)」, same provenance date. −63 B, 2 lines → 2.

Why the residual +5 could not be paid

The ruled addition is 773 bytes of content. At the gate's own 120-byte cap that is 7 lines
minimum
(6 × 120 = 720 bytes, less than 773), so no six-line spelling exists that keeps the
ruled substance — and the last thing that would have to go is 「不是出货缺陷」, which is the
ruling's own stated justification for declining the taxonomy. Every landed line was checked
against the cap; the only over-120-byte lines in the file are the two legacy quotation-exempt
ruling quotes that were already there (122 B and 125 B), left exactly as their author broke them.

The raise is authorized by the ruling itself, verbatim and untranslated, from comment 5494466874:

若触行数天花板,按 #13900 裁决同型引用本评论提额

That sentence and its comment id are also quoted beside the row in the CEILINGS map, per the
map's standing convention. Ceiling set to the exact landed count, headroom 0.

Gates

Every one run through scripts/pm/os-verify-lock.sh, exit code captured by redirect BEFORE any
pipe, on committed head f999175 (working tree clean at the time of the run).

gateexitits own verdict line
check:pm-skill-ratchet0✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/contract-review.md is 65 lines (ceiling 65; headroom 0).
check:pm-skill-ratchet --self-test0✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint0✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g).
check:skill-frame-sync0✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
check:skill-frame-freshness0✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:pm-dispatch-gates0✓ dispatch-gates self-test: 1240 cases pass.
check:pm-governed-merges0✓ check-governed-merges --self-test: 241 assertions (…)
check:nul-bytes0check-nul-bytes: OK (scanned 8004 text file(s) -- 8004 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

Full union, re-derived AFTER the last edit

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, no hand-fed
paths, re-run on head f999175 and byte-identical to the pre-commit derivation. It resolved the
change set from git itself — 2 paths, committed 2 / working tree 0 — and named 20 commands.

15 of 20 measured, all exit 0: the 8 above plus check:agent-test-spelling,
check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs,
check:entry-guard, check:parse-guard, check:pnpm-filter-targets,
check:watch-hint-literal, scripts/check-cross-package-test-inputs.mjs,
scripts/pm/bare-root-worklist.mjs --self-test.

5 of 20 NOT MEASURED — never green, never a flake. Each exited 3 with its own PREREQUISITE
text (「Nothing was measured: this gate exited before running a single check」): the fresh
worktree has no node_modules, which these five need. They are
scripts/check-ci-filter-parity.mjs, scripts/check-shard-attestation.mjs,
scripts/check-test-completeness.mjs, pnpm --filter @objectstack/lint run check:doc-formula-expressions,
and pnpm check:doc-authoring. This is a declared narrowing:
the diff touches one .claude/** markdown file and one scripts/pm/ gate script, so none of the
five has an input in this change set, and CI runs the farm exactly once regardless.

Beyond the derived families: the diff edits a gate script, so that script's own suite was run
separately — check-skill-line-ratchet.mjs --self-test (111 cases, above). The repo carries no
*.test.ts naming it; the two other scripts that mention it
(check-skills-token-ratchet.mjs, check-published-list-mirrors.mjs) reference it only in prose
and were run anyway, both exit 0.

No changeset: this releases nothing. scripts/check-empty-changeset.mjs enumerates the class in
its own words — 「It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/,
tests-only, and the like)」 — and its guidance for that class is exactly this PR's shape: apply
the skip-changeset label instead. Governed surface (.claude/**), so this PR stays draft.

Follow-up, recorded not fixed

SKILL.md is deliberately untouched. One line in it reads in tension with 「provisional」 and is
worth the maintainer's eye — in 「条款②入队闸门」: 「错误的 no 是记录在案、可审计的假申报」.
Calling a wrong no a 假申报 frames the seat, while the ruling says a declaration overturned at
tier 「不是席位过失,是机制按设计工作」. The two are reconcilable — the ruling's 「不是席位过失」
is about being overturned at tier, and 假申报 is about the one direction that ships — but the
wording is the kind that gets read alone. Not edited here: the ruling names one 落点, and this
is not it.

premise_false

  • Retracted — this entry was wrong, and it was published before it was caught. This section
    first said the card carried no claim comment with this session's URL. It does: comment
    5514292041, 2026-09-02, session_01LraLgQVGq8egUwfYZpbYt1, branch
    claude/issue-14047-clause2-classes, declaring Clause-②: no. The false reading was a READ
    artifact, not a fact about the card — the issue page's SSR payload preloads only the first 15
    timeline items and the claim comment sits past that page, so "absent from the payload" was
    taken for "absent". A direct comment read settles it. The brief's premise held; the assignee
    (os-litant) and pm:dispatched / domain:skills / priority:p2 were correct as stated.
  • The brief pointed at a 「sibling gate defining token counts」 for skills/** diffs. It does not
    apply: this diff touches .claude/skills/**, and the ratchet's own header states the published
    skills/ catalog is deliberately OUTSIDE the ceiling — a different surface.
  • Channel: this session's GitHub gate is CLOSED. Every repo-scoped REST path answers 403
    (GitHub access is not enabled for this session), authenticated and not, and gh is absent.
    Card reads went through the zero-quota public-repo payload channel; writes through MCP.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Generated by Claude Code

…echanical floor, judged conformance
The clause-② criterion carried no grading rule, so seats produced three
materially different kinds of "yes" in a day and two conservative
declarations were overturned at tier. This lands the ruling's answer in
`references/contract-review.md`:
- the claim-time `Clause-②: yes|no` declaration is PROVISIONAL by design —
it fixes the conservative dispatch tier, and the real gate is the at-tier
review at PR/report time, where the evidence and the cost live; a
declaration overturned there is the mechanism working, not a seat fault;
- the mechanical floor: any NEW exported symbol, or any NEW key on an
already-published payload, is always `yes` — checkable in the tree at
claim time, no judgement — and it locks the contract-review tier;
- the conformance class is deliberately NOT mechanized (populating an
already-declared field, re-selecting an input class between two published
codes): it needs at-tier judgement, and a claim that cannot tell
dispatches as `yes` — a false `yes` self-corrects, a false `no` ships.
The full taxonomy and the claim-time decision procedure are both declined
under the startup-scope lens, and that refusal is itself ruled content.
Paid into the line ratchet first, in real deleted bytes and never a re-wrap:
the 放行 bullet's restated FAIL / 卡在决策 triple (single source is SKILL.md's
条款②入队闸门, which this file's header already points at) and the 三样不变
clause (self-declared 「单源见主文件」, its governed-surface limb surviving
in-file in 落地前检三条) went, taking that bullet from 6 lines to 4. The
residual +5 is the ruled addition at its reasoned floor; the ceiling moves
60 → 65 on the ruling's own authorization, quoted verbatim beside the row.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation labels Sep 2, 2026
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Sep 2, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 22:52
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 04798d9Sep 2, 2026
42 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14047-clause2-classes branch September 2, 2026 23:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance - #14696

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes
Sep 2, 2026
Merged

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance#14696
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#14047

Lands the ruling's answer to the clause-② grading question in the ONE file the ruling names
as its 落点, and pays the line ratchet it crosses.

The ruling, verbatim and untranslated

Maintainer, 2026-09-01, comment 5494466874 (项目总监席 batch, maintainer's reply 逐字:「同意」):

裁决:(3) + (1) 的窄半 —— claim 声明按设计临时,真闸门在档位复审;新导出符号/新载荷键恒为 yes(维护者 2026-09-01,总监批 #23)

  1. (3) 获批:claim 时的 Clause-②: yes|no 声明按设计即临时(provisional) —— 它定派发档位的保守方向,⛔ 不是终审;真闸门在 PR/报告时的档位复审,证据与成本都在那里。声明被档位推翻不是席位过失,是机制按设计工作(本卡四标本中两例即如此);
  2. (1) 的窄半获批,作为机械地板:任何新导出符号或已发布载荷上的新键,恒为 yes —— claim 时可查树、无需判断,直接锁 fable 档;
  3. conformance 类(B/D 型)⛔ 不机械化:「向已声明面看齐 vs 收窄/加宽」的判别需要档位判断 —— 当天 validate-expressions has no flow leg for bare identifiers — a bare field reference in a flow condition passes objectstack validate clean #14089 即活标本(车道把 narrowing 读成 conformance 恢复,档位纠正)。裁定:claim 拿不准 ⇒ 按 yes 派 fable 档(地板的保守方向,假 yes 自纠、假 no 出货);
  4. (1) 全量分类学与 (2) 决策程序不建(创业镜头:现行机制四例四对,代价是复审轮不是出货缺陷);
  5. 落点:references/contract-review.md(受治面,skills 车道;若触行数天花板,按 [finding] The REST issues-list Link: rel="next" cursor silently returns 102 of 287 open issues — the dedup channel references/rest-channel.md prescribes #13900 裁决同型引用本评论提额)。⛔ 不重开四个标本 PR。

What landed — per item, 落点 | before | after

All three land as bullets in .claude/skills/pm-dispatch/references/contract-review.md,
in section 「载体纪律(挂与清)」, immediately after the 适用性 bullet — the file's existing
home for "what falls under clause ② and how it is graded". No new section: the ruling adds
grading rules to an applicability section that already exists.

#ruling item落点beforeafter
1claim declaration is provisional by design载体纪律, new bullet 「claim 声明按设计临时(provisional)」the file said nothing about the claim-time declaration at all — its first mention of Clause-② was as a place forward-looking facts liveClause-②: yes|no 只定派发档位的保守方向,⛔ 非终审;真闸门在 PR/报告时的档位复核 —— 证据与成本在那里。声明被档位推翻 = 机制按设计工作,⛔ 不作席位过失。」
2mechanical floor: new exported symbol / new published-payload key载体纪律, new bullet 「机械地板」, first limbabsent — the tier floor lived only in dispatch-gates.mjs --tier output, never in the review reference「任何新导出符号已发布载荷上的新键yes,直接锁契约复审档」, marked claim 时可查树、无需判断
3conformance class NOT mechanized; can't-tell dispatches as yessame bullet, second limbabsentconformance 类 ⛔ 不机械化(填充已声明字段、在两个已发布码之间重选输入类):判别需档位判断,claim 拿不准 ⇒ 按 yes 派契约复审档(假 yes 自纠、假 no 出货)」
4⛔ no full taxonomy, no decision proceduresame bullet, closing clauseabsent「⛔ 不建全量分类学与 claim 时决策程序(创业镜头:代价是复审轮)」

Ruling item 5 is the 落点 itself. Not done, deliberately: the four specimen PRs were not
reopened, and no file other than the reference (plus the ratchet's own CEILINGS row) is touched.

Provenance follows the file's own convention — 「维护者 2026-09-01「同意」」, by date and
quoted words. The file's header forbids issue ids (「⛔ 不引 issue 编号」) and
check:pm-skill-id-lint scans it against /#[0-9]{3,}/, so no card number appears in the
reference. The ruling's own authorizing sentence, which does carry an id, is quoted in the
CEILINGS map comment in scripts/pm/check-skill-line-ratchet.mjs — outside that gate's
SCAN_ROOT, which is .claude/skills/pm-dispatch only.

Line arithmetic

linesceilingheadroom
before60600
after payment (−2)58602
after the ruled addition (+7)65650

Payment came FIRST and it is real deleted bytes — not a re-wrap. 313 bytes went, and the
放行 bullet fell from 6 lines to 4.

Per-line 落点 of each deletion

  1. FAIL ⇒ 补丁轮;卡在决策 ⇒ 只进决策箱,⛔ 永不自裁 —— 真正设计分叉照旧升级维护者; (118 B)
    — restates SKILL.md 「条款②入队闸门」 almost phrase for phrase: 「FAIL ⇒ 补丁轮;⛔ 免复核不放行;
    真正设计分叉照旧进决策箱,席内复核 ⛔ 不替代维护者裁定」. Surviving anchor: SKILL.md, which
    this file's own header line 3 already points at — 「出处:主文件条款②闸门(原则/双肢与档位单源在彼)」.
    No rule is lost; the rule keeps its single source.
  2. **三样不变**:受管面照旧 draft-only + 终局两条(人工直合或授权批准钉 head 入队,单源见主文件)、⛔ 席位永不代批;FAIL / REWORK 原样;降档保险丝原样。 (195 B)
    — a self-declared restatement: it says 「单源见主文件」 in its own text. Surviving anchors, two:
    SKILL.md's ACCEPT 终局四件套 for the governed-surface limb, and — inside this same file —
    落地前检三条's 「受管面不适用,draft-only 终局不变」. Its remaining half (「FAIL / REWORK 原样;
    降档保险丝原样」) is a "nothing changed" statement carrying no rule, written when the in-seat
    rework landed; 降档保险丝 is the section directly below it.

Restatements measured and REJECTED as payment

A LINE ratchet cannot bank a deletion that does not cross a 120-byte boundary. These three are
real restatements, and deleting them buys nothing, so they were left alone rather than touched
for a number that would not move:

  • 停靠短暂(只防复核完成前误入队) in the 双载体 bullet — restates SKILL.md 「复核完成前短暂停靠」. −45 B, 3 lines → 3.
  • 非放行必要条件 in the 外部评审链 bullet — restates SKILL.md 「非放行前提」. −24 B, 4 lines → 4.
  • 可复审增量存在前永不挂标,提前挂已废止 in the 不预挂 bullet — restates SKILL.md 「随可复审契约增量同笔挂 … 前瞻预挂已废止(维护者 2026-08-28 裁定)」, same provenance date. −63 B, 2 lines → 2.

Why the residual +5 could not be paid

The ruled addition is 773 bytes of content. At the gate's own 120-byte cap that is 7 lines
minimum
(6 × 120 = 720 bytes, less than 773), so no six-line spelling exists that keeps the
ruled substance — and the last thing that would have to go is 「不是出货缺陷」, which is the
ruling's own stated justification for declining the taxonomy. Every landed line was checked
against the cap; the only over-120-byte lines in the file are the two legacy quotation-exempt
ruling quotes that were already there (122 B and 125 B), left exactly as their author broke them.

The raise is authorized by the ruling itself, verbatim and untranslated, from comment 5494466874:

若触行数天花板,按 #13900 裁决同型引用本评论提额

That sentence and its comment id are also quoted beside the row in the CEILINGS map, per the
map's standing convention. Ceiling set to the exact landed count, headroom 0.

Gates

Every one run through scripts/pm/os-verify-lock.sh, exit code captured by redirect BEFORE any
pipe, on committed head f999175 (working tree clean at the time of the run).

gateexitits own verdict line
check:pm-skill-ratchet0✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/contract-review.md is 65 lines (ceiling 65; headroom 0).
check:pm-skill-ratchet --self-test0✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint0✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g).
check:skill-frame-sync0✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
check:skill-frame-freshness0✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:pm-dispatch-gates0✓ dispatch-gates self-test: 1240 cases pass.
check:pm-governed-merges0✓ check-governed-merges --self-test: 241 assertions (…)
check:nul-bytes0check-nul-bytes: OK (scanned 8004 text file(s) -- 8004 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

Full union, re-derived AFTER the last edit

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, no hand-fed
paths, re-run on head f999175 and byte-identical to the pre-commit derivation. It resolved the
change set from git itself — 2 paths, committed 2 / working tree 0 — and named 20 commands.

15 of 20 measured, all exit 0: the 8 above plus check:agent-test-spelling,
check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs,
check:entry-guard, check:parse-guard, check:pnpm-filter-targets,
check:watch-hint-literal, scripts/check-cross-package-test-inputs.mjs,
scripts/pm/bare-root-worklist.mjs --self-test.

5 of 20 NOT MEASURED — never green, never a flake. Each exited 3 with its own PREREQUISITE
text (「Nothing was measured: this gate exited before running a single check」): the fresh
worktree has no node_modules, which these five need. They are
scripts/check-ci-filter-parity.mjs, scripts/check-shard-attestation.mjs,
scripts/check-test-completeness.mjs, pnpm --filter @objectstack/lint run check:doc-formula-expressions,
and pnpm check:doc-authoring. This is a declared narrowing:
the diff touches one .claude/** markdown file and one scripts/pm/ gate script, so none of the
five has an input in this change set, and CI runs the farm exactly once regardless.

Beyond the derived families: the diff edits a gate script, so that script's own suite was run
separately — check-skill-line-ratchet.mjs --self-test (111 cases, above). The repo carries no
*.test.ts naming it; the two other scripts that mention it
(check-skills-token-ratchet.mjs, check-published-list-mirrors.mjs) reference it only in prose
and were run anyway, both exit 0.

No changeset: this releases nothing. scripts/check-empty-changeset.mjs enumerates the class in
its own words — 「It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/,
tests-only, and the like)」 — and its guidance for that class is exactly this PR's shape: apply
the skip-changeset label instead. Governed surface (.claude/**), so this PR stays draft.

Follow-up, recorded not fixed

SKILL.md is deliberately untouched. One line in it reads in tension with 「provisional」 and is
worth the maintainer's eye — in 「条款②入队闸门」: 「错误的 no 是记录在案、可审计的假申报」.
Calling a wrong no a 假申报 frames the seat, while the ruling says a declaration overturned at
tier 「不是席位过失,是机制按设计工作」. The two are reconcilable — the ruling's 「不是席位过失」
is about being overturned at tier, and 假申报 is about the one direction that ships — but the
wording is the kind that gets read alone. Not edited here: the ruling names one 落点, and this
is not it.

premise_false

  • Retracted — this entry was wrong, and it was published before it was caught. This section
    first said the card carried no claim comment with this session's URL. It does: comment
    5514292041, 2026-09-02, session_01LraLgQVGq8egUwfYZpbYt1, branch
    claude/issue-14047-clause2-classes, declaring Clause-②: no. The false reading was a READ
    artifact, not a fact about the card — the issue page's SSR payload preloads only the first 15
    timeline items and the claim comment sits past that page, so "absent from the payload" was
    taken for "absent". A direct comment read settles it. The brief's premise held; the assignee
    (os-litant) and pm:dispatched / domain:skills / priority:p2 were correct as stated.
  • The brief pointed at a 「sibling gate defining token counts」 for skills/** diffs. It does not
    apply: this diff touches .claude/skills/**, and the ratchet's own header states the published
    skills/ catalog is deliberately OUTSIDE the ceiling — a different surface.
  • Channel: this session's GitHub gate is CLOSED. Every repo-scoped REST path answers 403
    (GitHub access is not enabled for this session), authenticated and not, and gh is absent.
    Card reads went through the zero-quota public-repo payload channel; writes through MCP.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Generated by Claude Code

…echanical floor, judged conformance
The clause-② criterion carried no grading rule, so seats produced three
materially different kinds of "yes" in a day and two conservative
declarations were overturned at tier. This lands the ruling's answer in
`references/contract-review.md`:
- the claim-time `Clause-②: yes|no` declaration is PROVISIONAL by design —
it fixes the conservative dispatch tier, and the real gate is the at-tier
review at PR/report time, where the evidence and the cost live; a
declaration overturned there is the mechanism working, not a seat fault;
- the mechanical floor: any NEW exported symbol, or any NEW key on an
already-published payload, is always `yes` — checkable in the tree at
claim time, no judgement — and it locks the contract-review tier;
- the conformance class is deliberately NOT mechanized (populating an
already-declared field, re-selecting an input class between two published
codes): it needs at-tier judgement, and a claim that cannot tell
dispatches as `yes` — a false `yes` self-corrects, a false `no` ships.
The full taxonomy and the claim-time decision procedure are both declined
under the startup-scope lens, and that refusal is itself ruled content.
Paid into the line ratchet first, in real deleted bytes and never a re-wrap:
the 放行 bullet's restated FAIL / 卡在决策 triple (single source is SKILL.md's
条款②入队闸门, which this file's header already points at) and the 三样不变
clause (self-declared 「单源见主文件」, its governed-surface limb surviving
in-file in 落地前检三条) went, taking that bullet from 6 lines to 4. The
residual +5 is the ruled addition at its reasoned floor; the ceiling moves
60 → 65 on the ruling's own authorization, quoted verbatim beside the row.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation labels Sep 2, 2026
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Sep 2, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 22:52
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 04798d9Sep 2, 2026
42 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14047-clause2-classes branch September 2, 2026 23:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance - #14696

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes
Sep 2, 2026
Merged

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance#14696
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#14047

Lands the ruling's answer to the clause-② grading question in the ONE file the ruling names
as its 落点, and pays the line ratchet it crosses.

The ruling, verbatim and untranslated

Maintainer, 2026-09-01, comment 5494466874 (项目总监席 batch, maintainer's reply 逐字:「同意」):

裁决:(3) + (1) 的窄半 —— claim 声明按设计临时,真闸门在档位复审;新导出符号/新载荷键恒为 yes(维护者 2026-09-01,总监批 #23)

  1. (3) 获批:claim 时的 Clause-②: yes|no 声明按设计即临时(provisional) —— 它定派发档位的保守方向,⛔ 不是终审;真闸门在 PR/报告时的档位复审,证据与成本都在那里。声明被档位推翻不是席位过失,是机制按设计工作(本卡四标本中两例即如此);
  2. (1) 的窄半获批,作为机械地板:任何新导出符号或已发布载荷上的新键,恒为 yes —— claim 时可查树、无需判断,直接锁 fable 档;
  3. conformance 类(B/D 型)⛔ 不机械化:「向已声明面看齐 vs 收窄/加宽」的判别需要档位判断 —— 当天 validate-expressions has no flow leg for bare identifiers — a bare field reference in a flow condition passes objectstack validate clean #14089 即活标本(车道把 narrowing 读成 conformance 恢复,档位纠正)。裁定:claim 拿不准 ⇒ 按 yes 派 fable 档(地板的保守方向,假 yes 自纠、假 no 出货);
  4. (1) 全量分类学与 (2) 决策程序不建(创业镜头:现行机制四例四对,代价是复审轮不是出货缺陷);
  5. 落点:references/contract-review.md(受治面,skills 车道;若触行数天花板,按 [finding] The REST issues-list Link: rel="next" cursor silently returns 102 of 287 open issues — the dedup channel references/rest-channel.md prescribes #13900 裁决同型引用本评论提额)。⛔ 不重开四个标本 PR。

What landed — per item, 落点 | before | after

All three land as bullets in .claude/skills/pm-dispatch/references/contract-review.md,
in section 「载体纪律(挂与清)」, immediately after the 适用性 bullet — the file's existing
home for "what falls under clause ② and how it is graded". No new section: the ruling adds
grading rules to an applicability section that already exists.

#ruling item落点beforeafter
1claim declaration is provisional by design载体纪律, new bullet 「claim 声明按设计临时(provisional)」the file said nothing about the claim-time declaration at all — its first mention of Clause-② was as a place forward-looking facts liveClause-②: yes|no 只定派发档位的保守方向,⛔ 非终审;真闸门在 PR/报告时的档位复核 —— 证据与成本在那里。声明被档位推翻 = 机制按设计工作,⛔ 不作席位过失。」
2mechanical floor: new exported symbol / new published-payload key载体纪律, new bullet 「机械地板」, first limbabsent — the tier floor lived only in dispatch-gates.mjs --tier output, never in the review reference「任何新导出符号已发布载荷上的新键yes,直接锁契约复审档」, marked claim 时可查树、无需判断
3conformance class NOT mechanized; can't-tell dispatches as yessame bullet, second limbabsentconformance 类 ⛔ 不机械化(填充已声明字段、在两个已发布码之间重选输入类):判别需档位判断,claim 拿不准 ⇒ 按 yes 派契约复审档(假 yes 自纠、假 no 出货)」
4⛔ no full taxonomy, no decision proceduresame bullet, closing clauseabsent「⛔ 不建全量分类学与 claim 时决策程序(创业镜头:代价是复审轮)」

Ruling item 5 is the 落点 itself. Not done, deliberately: the four specimen PRs were not
reopened, and no file other than the reference (plus the ratchet's own CEILINGS row) is touched.

Provenance follows the file's own convention — 「维护者 2026-09-01「同意」」, by date and
quoted words. The file's header forbids issue ids (「⛔ 不引 issue 编号」) and
check:pm-skill-id-lint scans it against /#[0-9]{3,}/, so no card number appears in the
reference. The ruling's own authorizing sentence, which does carry an id, is quoted in the
CEILINGS map comment in scripts/pm/check-skill-line-ratchet.mjs — outside that gate's
SCAN_ROOT, which is .claude/skills/pm-dispatch only.

Line arithmetic

linesceilingheadroom
before60600
after payment (−2)58602
after the ruled addition (+7)65650

Payment came FIRST and it is real deleted bytes — not a re-wrap. 313 bytes went, and the
放行 bullet fell from 6 lines to 4.

Per-line 落点 of each deletion

  1. FAIL ⇒ 补丁轮;卡在决策 ⇒ 只进决策箱,⛔ 永不自裁 —— 真正设计分叉照旧升级维护者; (118 B)
    — restates SKILL.md 「条款②入队闸门」 almost phrase for phrase: 「FAIL ⇒ 补丁轮;⛔ 免复核不放行;
    真正设计分叉照旧进决策箱,席内复核 ⛔ 不替代维护者裁定」. Surviving anchor: SKILL.md, which
    this file's own header line 3 already points at — 「出处:主文件条款②闸门(原则/双肢与档位单源在彼)」.
    No rule is lost; the rule keeps its single source.
  2. **三样不变**:受管面照旧 draft-only + 终局两条(人工直合或授权批准钉 head 入队,单源见主文件)、⛔ 席位永不代批;FAIL / REWORK 原样;降档保险丝原样。 (195 B)
    — a self-declared restatement: it says 「单源见主文件」 in its own text. Surviving anchors, two:
    SKILL.md's ACCEPT 终局四件套 for the governed-surface limb, and — inside this same file —
    落地前检三条's 「受管面不适用,draft-only 终局不变」. Its remaining half (「FAIL / REWORK 原样;
    降档保险丝原样」) is a "nothing changed" statement carrying no rule, written when the in-seat
    rework landed; 降档保险丝 is the section directly below it.

Restatements measured and REJECTED as payment

A LINE ratchet cannot bank a deletion that does not cross a 120-byte boundary. These three are
real restatements, and deleting them buys nothing, so they were left alone rather than touched
for a number that would not move:

  • 停靠短暂(只防复核完成前误入队) in the 双载体 bullet — restates SKILL.md 「复核完成前短暂停靠」. −45 B, 3 lines → 3.
  • 非放行必要条件 in the 外部评审链 bullet — restates SKILL.md 「非放行前提」. −24 B, 4 lines → 4.
  • 可复审增量存在前永不挂标,提前挂已废止 in the 不预挂 bullet — restates SKILL.md 「随可复审契约增量同笔挂 … 前瞻预挂已废止(维护者 2026-08-28 裁定)」, same provenance date. −63 B, 2 lines → 2.

Why the residual +5 could not be paid

The ruled addition is 773 bytes of content. At the gate's own 120-byte cap that is 7 lines
minimum
(6 × 120 = 720 bytes, less than 773), so no six-line spelling exists that keeps the
ruled substance — and the last thing that would have to go is 「不是出货缺陷」, which is the
ruling's own stated justification for declining the taxonomy. Every landed line was checked
against the cap; the only over-120-byte lines in the file are the two legacy quotation-exempt
ruling quotes that were already there (122 B and 125 B), left exactly as their author broke them.

The raise is authorized by the ruling itself, verbatim and untranslated, from comment 5494466874:

若触行数天花板,按 #13900 裁决同型引用本评论提额

That sentence and its comment id are also quoted beside the row in the CEILINGS map, per the
map's standing convention. Ceiling set to the exact landed count, headroom 0.

Gates

Every one run through scripts/pm/os-verify-lock.sh, exit code captured by redirect BEFORE any
pipe, on committed head f999175 (working tree clean at the time of the run).

gateexitits own verdict line
check:pm-skill-ratchet0✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/contract-review.md is 65 lines (ceiling 65; headroom 0).
check:pm-skill-ratchet --self-test0✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint0✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g).
check:skill-frame-sync0✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
check:skill-frame-freshness0✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:pm-dispatch-gates0✓ dispatch-gates self-test: 1240 cases pass.
check:pm-governed-merges0✓ check-governed-merges --self-test: 241 assertions (…)
check:nul-bytes0check-nul-bytes: OK (scanned 8004 text file(s) -- 8004 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

Full union, re-derived AFTER the last edit

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, no hand-fed
paths, re-run on head f999175 and byte-identical to the pre-commit derivation. It resolved the
change set from git itself — 2 paths, committed 2 / working tree 0 — and named 20 commands.

15 of 20 measured, all exit 0: the 8 above plus check:agent-test-spelling,
check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs,
check:entry-guard, check:parse-guard, check:pnpm-filter-targets,
check:watch-hint-literal, scripts/check-cross-package-test-inputs.mjs,
scripts/pm/bare-root-worklist.mjs --self-test.

5 of 20 NOT MEASURED — never green, never a flake. Each exited 3 with its own PREREQUISITE
text (「Nothing was measured: this gate exited before running a single check」): the fresh
worktree has no node_modules, which these five need. They are
scripts/check-ci-filter-parity.mjs, scripts/check-shard-attestation.mjs,
scripts/check-test-completeness.mjs, pnpm --filter @objectstack/lint run check:doc-formula-expressions,
and pnpm check:doc-authoring. This is a declared narrowing:
the diff touches one .claude/** markdown file and one scripts/pm/ gate script, so none of the
five has an input in this change set, and CI runs the farm exactly once regardless.

Beyond the derived families: the diff edits a gate script, so that script's own suite was run
separately — check-skill-line-ratchet.mjs --self-test (111 cases, above). The repo carries no
*.test.ts naming it; the two other scripts that mention it
(check-skills-token-ratchet.mjs, check-published-list-mirrors.mjs) reference it only in prose
and were run anyway, both exit 0.

No changeset: this releases nothing. scripts/check-empty-changeset.mjs enumerates the class in
its own words — 「It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/,
tests-only, and the like)」 — and its guidance for that class is exactly this PR's shape: apply
the skip-changeset label instead. Governed surface (.claude/**), so this PR stays draft.

Follow-up, recorded not fixed

SKILL.md is deliberately untouched. One line in it reads in tension with 「provisional」 and is
worth the maintainer's eye — in 「条款②入队闸门」: 「错误的 no 是记录在案、可审计的假申报」.
Calling a wrong no a 假申报 frames the seat, while the ruling says a declaration overturned at
tier 「不是席位过失,是机制按设计工作」. The two are reconcilable — the ruling's 「不是席位过失」
is about being overturned at tier, and 假申报 is about the one direction that ships — but the
wording is the kind that gets read alone. Not edited here: the ruling names one 落点, and this
is not it.

premise_false

  • Retracted — this entry was wrong, and it was published before it was caught. This section
    first said the card carried no claim comment with this session's URL. It does: comment
    5514292041, 2026-09-02, session_01LraLgQVGq8egUwfYZpbYt1, branch
    claude/issue-14047-clause2-classes, declaring Clause-②: no. The false reading was a READ
    artifact, not a fact about the card — the issue page's SSR payload preloads only the first 15
    timeline items and the claim comment sits past that page, so "absent from the payload" was
    taken for "absent". A direct comment read settles it. The brief's premise held; the assignee
    (os-litant) and pm:dispatched / domain:skills / priority:p2 were correct as stated.
  • The brief pointed at a 「sibling gate defining token counts」 for skills/** diffs. It does not
    apply: this diff touches .claude/skills/**, and the ratchet's own header states the published
    skills/ catalog is deliberately OUTSIDE the ceiling — a different surface.
  • Channel: this session's GitHub gate is CLOSED. Every repo-scoped REST path answers 403
    (GitHub access is not enabled for this session), authenticated and not, and gh is absent.
    Card reads went through the zero-quota public-repo payload channel; writes through MCP.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Generated by Claude Code

…echanical floor, judged conformance
The clause-② criterion carried no grading rule, so seats produced three
materially different kinds of "yes" in a day and two conservative
declarations were overturned at tier. This lands the ruling's answer in
`references/contract-review.md`:
- the claim-time `Clause-②: yes|no` declaration is PROVISIONAL by design —
it fixes the conservative dispatch tier, and the real gate is the at-tier
review at PR/report time, where the evidence and the cost live; a
declaration overturned there is the mechanism working, not a seat fault;
- the mechanical floor: any NEW exported symbol, or any NEW key on an
already-published payload, is always `yes` — checkable in the tree at
claim time, no judgement — and it locks the contract-review tier;
- the conformance class is deliberately NOT mechanized (populating an
already-declared field, re-selecting an input class between two published
codes): it needs at-tier judgement, and a claim that cannot tell
dispatches as `yes` — a false `yes` self-corrects, a false `no` ships.
The full taxonomy and the claim-time decision procedure are both declined
under the startup-scope lens, and that refusal is itself ruled content.
Paid into the line ratchet first, in real deleted bytes and never a re-wrap:
the 放行 bullet's restated FAIL / 卡在决策 triple (single source is SKILL.md's
条款②入队闸门, which this file's header already points at) and the 三样不变
clause (self-declared 「单源见主文件」, its governed-surface limb surviving
in-file in 落地前检三条) went, taking that bullet from 6 lines to 4. The
residual +5 is the ruled addition at its reasoned floor; the ceiling moves
60 → 65 on the ruling's own authorization, quoted verbatim beside the row.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation labels Sep 2, 2026
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Sep 2, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 22:52
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 04798d9Sep 2, 2026
42 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14047-clause2-classes branch September 2, 2026 23:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance - #14696

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes
Sep 2, 2026
Merged

docs(pm-dispatch): rule how clause ② is graded — provisional claim, mechanical floor, judged conformance#14696
os-zhuang merged 1 commit into
mainfrom
claude/issue-14047-clause2-classes

Conversation

@os-litant

@os-litantos-litant commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes#14047

Lands the ruling's answer to the clause-② grading question in the ONE file the ruling names
as its 落点, and pays the line ratchet it crosses.

The ruling, verbatim and untranslated

Maintainer, 2026-09-01, comment 5494466874 (项目总监席 batch, maintainer's reply 逐字:「同意」):

裁决:(3) + (1) 的窄半 —— claim 声明按设计临时,真闸门在档位复审;新导出符号/新载荷键恒为 yes(维护者 2026-09-01,总监批 #23)

  1. (3) 获批:claim 时的 Clause-②: yes|no 声明按设计即临时(provisional) —— 它定派发档位的保守方向,⛔ 不是终审;真闸门在 PR/报告时的档位复审,证据与成本都在那里。声明被档位推翻不是席位过失,是机制按设计工作(本卡四标本中两例即如此);
  2. (1) 的窄半获批,作为机械地板:任何新导出符号或已发布载荷上的新键,恒为 yes —— claim 时可查树、无需判断,直接锁 fable 档;
  3. conformance 类(B/D 型)⛔ 不机械化:「向已声明面看齐 vs 收窄/加宽」的判别需要档位判断 —— 当天 validate-expressions has no flow leg for bare identifiers — a bare field reference in a flow condition passes objectstack validate clean #14089 即活标本(车道把 narrowing 读成 conformance 恢复,档位纠正)。裁定:claim 拿不准 ⇒ 按 yes 派 fable 档(地板的保守方向,假 yes 自纠、假 no 出货);
  4. (1) 全量分类学与 (2) 决策程序不建(创业镜头:现行机制四例四对,代价是复审轮不是出货缺陷);
  5. 落点:references/contract-review.md(受治面,skills 车道;若触行数天花板,按 [finding] The REST issues-list Link: rel="next" cursor silently returns 102 of 287 open issues — the dedup channel references/rest-channel.md prescribes #13900 裁决同型引用本评论提额)。⛔ 不重开四个标本 PR。

What landed — per item, 落点 | before | after

All three land as bullets in .claude/skills/pm-dispatch/references/contract-review.md,
in section 「载体纪律(挂与清)」, immediately after the 适用性 bullet — the file's existing
home for "what falls under clause ② and how it is graded". No new section: the ruling adds
grading rules to an applicability section that already exists.

#ruling item落点beforeafter
1claim declaration is provisional by design载体纪律, new bullet 「claim 声明按设计临时(provisional)」the file said nothing about the claim-time declaration at all — its first mention of Clause-② was as a place forward-looking facts liveClause-②: yes|no 只定派发档位的保守方向,⛔ 非终审;真闸门在 PR/报告时的档位复核 —— 证据与成本在那里。声明被档位推翻 = 机制按设计工作,⛔ 不作席位过失。」
2mechanical floor: new exported symbol / new published-payload key载体纪律, new bullet 「机械地板」, first limbabsent — the tier floor lived only in dispatch-gates.mjs --tier output, never in the review reference「任何新导出符号已发布载荷上的新键yes,直接锁契约复审档」, marked claim 时可查树、无需判断
3conformance class NOT mechanized; can't-tell dispatches as yessame bullet, second limbabsentconformance 类 ⛔ 不机械化(填充已声明字段、在两个已发布码之间重选输入类):判别需档位判断,claim 拿不准 ⇒ 按 yes 派契约复审档(假 yes 自纠、假 no 出货)」
4⛔ no full taxonomy, no decision proceduresame bullet, closing clauseabsent「⛔ 不建全量分类学与 claim 时决策程序(创业镜头:代价是复审轮)」

Ruling item 5 is the 落点 itself. Not done, deliberately: the four specimen PRs were not
reopened, and no file other than the reference (plus the ratchet's own CEILINGS row) is touched.

Provenance follows the file's own convention — 「维护者 2026-09-01「同意」」, by date and
quoted words. The file's header forbids issue ids (「⛔ 不引 issue 编号」) and
check:pm-skill-id-lint scans it against /#[0-9]{3,}/, so no card number appears in the
reference. The ruling's own authorizing sentence, which does carry an id, is quoted in the
CEILINGS map comment in scripts/pm/check-skill-line-ratchet.mjs — outside that gate's
SCAN_ROOT, which is .claude/skills/pm-dispatch only.

Line arithmetic

linesceilingheadroom
before60600
after payment (−2)58602
after the ruled addition (+7)65650

Payment came FIRST and it is real deleted bytes — not a re-wrap. 313 bytes went, and the
放行 bullet fell from 6 lines to 4.

Per-line 落点 of each deletion

  1. FAIL ⇒ 补丁轮;卡在决策 ⇒ 只进决策箱,⛔ 永不自裁 —— 真正设计分叉照旧升级维护者; (118 B)
    — restates SKILL.md 「条款②入队闸门」 almost phrase for phrase: 「FAIL ⇒ 补丁轮;⛔ 免复核不放行;
    真正设计分叉照旧进决策箱,席内复核 ⛔ 不替代维护者裁定」. Surviving anchor: SKILL.md, which
    this file's own header line 3 already points at — 「出处:主文件条款②闸门(原则/双肢与档位单源在彼)」.
    No rule is lost; the rule keeps its single source.
  2. **三样不变**:受管面照旧 draft-only + 终局两条(人工直合或授权批准钉 head 入队,单源见主文件)、⛔ 席位永不代批;FAIL / REWORK 原样;降档保险丝原样。 (195 B)
    — a self-declared restatement: it says 「单源见主文件」 in its own text. Surviving anchors, two:
    SKILL.md's ACCEPT 终局四件套 for the governed-surface limb, and — inside this same file —
    落地前检三条's 「受管面不适用,draft-only 终局不变」. Its remaining half (「FAIL / REWORK 原样;
    降档保险丝原样」) is a "nothing changed" statement carrying no rule, written when the in-seat
    rework landed; 降档保险丝 is the section directly below it.

Restatements measured and REJECTED as payment

A LINE ratchet cannot bank a deletion that does not cross a 120-byte boundary. These three are
real restatements, and deleting them buys nothing, so they were left alone rather than touched
for a number that would not move:

  • 停靠短暂(只防复核完成前误入队) in the 双载体 bullet — restates SKILL.md 「复核完成前短暂停靠」. −45 B, 3 lines → 3.
  • 非放行必要条件 in the 外部评审链 bullet — restates SKILL.md 「非放行前提」. −24 B, 4 lines → 4.
  • 可复审增量存在前永不挂标,提前挂已废止 in the 不预挂 bullet — restates SKILL.md 「随可复审契约增量同笔挂 … 前瞻预挂已废止(维护者 2026-08-28 裁定)」, same provenance date. −63 B, 2 lines → 2.

Why the residual +5 could not be paid

The ruled addition is 773 bytes of content. At the gate's own 120-byte cap that is 7 lines
minimum
(6 × 120 = 720 bytes, less than 773), so no six-line spelling exists that keeps the
ruled substance — and the last thing that would have to go is 「不是出货缺陷」, which is the
ruling's own stated justification for declining the taxonomy. Every landed line was checked
against the cap; the only over-120-byte lines in the file are the two legacy quotation-exempt
ruling quotes that were already there (122 B and 125 B), left exactly as their author broke them.

The raise is authorized by the ruling itself, verbatim and untranslated, from comment 5494466874:

若触行数天花板,按 #13900 裁决同型引用本评论提额

That sentence and its comment id are also quoted beside the row in the CEILINGS map, per the
map's standing convention. Ceiling set to the exact landed count, headroom 0.

Gates

Every one run through scripts/pm/os-verify-lock.sh, exit code captured by redirect BEFORE any
pipe, on committed head f999175 (working tree clean at the time of the run).

gateexitits own verdict line
check:pm-skill-ratchet0✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/contract-review.md is 65 lines (ceiling 65; headroom 0).
check:pm-skill-ratchet --self-test0✓ check-skill-line-ratchet self-test: 111 cases pass.
check:pm-skill-id-lint0✓ check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g).
check:skill-frame-sync0✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files
check:skill-frame-freshness0✓ check-skill-frame-freshness: the decision frame in this tree is current with origin/main (fetched just now).
check:pm-dispatch-gates0✓ dispatch-gates self-test: 1240 cases pass.
check:pm-governed-merges0✓ check-governed-merges --self-test: 241 assertions (…)
check:nul-bytes0check-nul-bytes: OK (scanned 8004 text file(s) -- 8004 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).

Full union, re-derived AFTER the last edit

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, no hand-fed
paths, re-run on head f999175 and byte-identical to the pre-commit derivation. It resolved the
change set from git itself — 2 paths, committed 2 / working tree 0 — and named 20 commands.

15 of 20 measured, all exit 0: the 8 above plus check:agent-test-spelling,
check:bash32-floor, check:cli-command-ids, check:cross-package-test-inputs,
check:entry-guard, check:parse-guard, check:pnpm-filter-targets,
check:watch-hint-literal, scripts/check-cross-package-test-inputs.mjs,
scripts/pm/bare-root-worklist.mjs --self-test.

5 of 20 NOT MEASURED — never green, never a flake. Each exited 3 with its own PREREQUISITE
text (「Nothing was measured: this gate exited before running a single check」): the fresh
worktree has no node_modules, which these five need. They are
scripts/check-ci-filter-parity.mjs, scripts/check-shard-attestation.mjs,
scripts/check-test-completeness.mjs, pnpm --filter @objectstack/lint run check:doc-formula-expressions,
and pnpm check:doc-authoring. This is a declared narrowing:
the diff touches one .claude/** markdown file and one scripts/pm/ gate script, so none of the
five has an input in this change set, and CI runs the farm exactly once regardless.

Beyond the derived families: the diff edits a gate script, so that script's own suite was run
separately — check-skill-line-ratchet.mjs --self-test (111 cases, above). The repo carries no
*.test.ts naming it; the two other scripts that mention it
(check-skills-token-ratchet.mjs, check-published-list-mirrors.mjs) reference it only in prose
and were run anyway, both exit 0.

No changeset: this releases nothing. scripts/check-empty-changeset.mjs enumerates the class in
its own words — 「It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/,
tests-only, and the like)」 — and its guidance for that class is exactly this PR's shape: apply
the skip-changeset label instead. Governed surface (.claude/**), so this PR stays draft.

Follow-up, recorded not fixed

SKILL.md is deliberately untouched. One line in it reads in tension with 「provisional」 and is
worth the maintainer's eye — in 「条款②入队闸门」: 「错误的 no 是记录在案、可审计的假申报」.
Calling a wrong no a 假申报 frames the seat, while the ruling says a declaration overturned at
tier 「不是席位过失,是机制按设计工作」. The two are reconcilable — the ruling's 「不是席位过失」
is about being overturned at tier, and 假申报 is about the one direction that ships — but the
wording is the kind that gets read alone. Not edited here: the ruling names one 落点, and this
is not it.

premise_false

  • Retracted — this entry was wrong, and it was published before it was caught. This section
    first said the card carried no claim comment with this session's URL. It does: comment
    5514292041, 2026-09-02, session_01LraLgQVGq8egUwfYZpbYt1, branch
    claude/issue-14047-clause2-classes, declaring Clause-②: no. The false reading was a READ
    artifact, not a fact about the card — the issue page's SSR payload preloads only the first 15
    timeline items and the claim comment sits past that page, so "absent from the payload" was
    taken for "absent". A direct comment read settles it. The brief's premise held; the assignee
    (os-litant) and pm:dispatched / domain:skills / priority:p2 were correct as stated.
  • The brief pointed at a 「sibling gate defining token counts」 for skills/** diffs. It does not
    apply: this diff touches .claude/skills/**, and the ratchet's own header states the published
    skills/ catalog is deliberately OUTSIDE the ceiling — a different surface.
  • Channel: this session's GitHub gate is CLOSED. Every repo-scoped REST path answers 403
    (GitHub access is not enabled for this session), authenticated and not, and gh is absent.
    Card reads went through the zero-quota public-repo payload channel; writes through MCP.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1

Generated by Claude Code

…echanical floor, judged conformance
The clause-② criterion carried no grading rule, so seats produced three
materially different kinds of "yes" in a day and two conservative
declarations were overturned at tier. This lands the ruling's answer in
`references/contract-review.md`:
- the claim-time `Clause-②: yes|no` declaration is PROVISIONAL by design —
it fixes the conservative dispatch tier, and the real gate is the at-tier
review at PR/report time, where the evidence and the cost live; a
declaration overturned there is the mechanism working, not a seat fault;
- the mechanical floor: any NEW exported symbol, or any NEW key on an
already-published payload, is always `yes` — checkable in the tree at
claim time, no judgement — and it locks the contract-review tier;
- the conformance class is deliberately NOT mechanized (populating an
already-declared field, re-selecting an input class between two published
codes): it needs at-tier judgement, and a claim that cannot tell
dispatches as `yes` — a false `yes` self-corrects, a false `no` ships.
The full taxonomy and the claim-time decision procedure are both declined
under the startup-scope lens, and that refusal is itself ruled content.
Paid into the line ratchet first, in real deleted bytes and never a re-wrap:
the 放行 bullet's restated FAIL / 卡在决策 triple (single source is SKILL.md's
条款②入队闸门, which this file's header already points at) and the 三样不变
clause (self-declared 「单源见主文件」, its governed-surface limb surviving
in-file in 落地前检三条) went, taking that bullet from 6 lines to 4. The
residual +5 is the ruled addition at its reasoned floor; the ceiling moves
60 → 65 on the ruling's own authorization, quoted verbatim beside the row.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation labels Sep 2, 2026
@os-litantos-litant added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Sep 2, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review September 2, 2026 22:52
@os-zhuang
os-zhuang added this pull request to the merge queueSep 2, 2026
Merged via the queue into main with commit 04798d9Sep 2, 2026
42 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-14047-clause2-classes branch September 2, 2026 23:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

3 participants

@os-litant@os-zhuang@claude