Skip to content

feat(governed): an authorized APPROVED review lifts the over-5000-line SIZE limb, as it lifts a Tier H path - #20159

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-20153-size-limb-approval-lift
Sep 27, 2026
Merged

os-zhuang merged 1 commit into
mainfrom
claude/issue-20153-size-limb-approval-lift

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #20153

Clause-②: no

What this lands

The maintainer's ruling of 2026-09-27 (card #20153, verbatim, untranslated): 「所以阈值写死成 5000 行 , 维护者已经批准了就是可以合并。」

An authorized APPROVED review now lifts the SIZE limb exactly as it lifts a Tier H path. "Authorized" is an account in GOVERNED_APPROVERS; the predicate is the governed leg's own — latest-decisive review per account, on ANY commit (the 2026-09-04 unpinning), dismissed / superseded / unauthorized approvals never count, an unreadable review list fails closed. After the approval the owning seat lands the PR through the queue; the maintainer's direct merge stays the other landing.

Unchanged, as the card requires: the threshold (5,000), the strict comparison, "generated files included", the FORK limb (no approval lifts a fork), the post-merge sweep (it still lists every oversized landing — it hands the predicate no approval), GOVERNED_APPROVERS, the Tier S rule, and the exit-code register (no new code).

Mechanism — one derivation, one predicate, imported

  • scripts/pm/check-governed-merges.mjs (the predicate's home): testVerdict(paths, { size, approval }) takes the approval verdict as DATA; sizeVerdict(size, approval) adds lifted (approvers, the commit each approval was given on, the ruling's citation) and approvalState; sizeLiftFrom reads only the verdict's state and its approvals field; sizeLimbFires(size) = over the line AND not lifted; landsByHumanMerge reads it. exceeds still reads true over the line — the lift is a second fact beside the number, never a change to the number.
  • scripts/pm/check-governed-queue-guard.mjs (the queue leg): the SIZE leg REUSES the governed leg's authorizedApprovalVerdict object for a pull request that leg already read, else runs the same derivation on one review read of its own — only for a pull request that is OVER the line (a within PR and an unreadable size make no review read; both pinned with throwing spies). authorizedApprovalVerdict now also returns approvals: [{ login, commitId }] — the field only the authorized reduction carries, so the generic approvalVerdict (which never asked WHO) cannot lift. The guard spells no lift condition of its own; a self-test pin reads its source to prove it.
  • Exit codes: lifted → 0 (the SIZE block prints approver, commit, and objectstack#20153 with the ruling verbatim); no / unauthorized / dismissed / superseded approval → 8, as today; unreadable size → 9, as today; an unreadable review list on an oversized PR → 8 (over the line, no lift proven; the words say the list could not be read). Code 9 stays "the SIZE could not be read". Precedence governed-then-size is unchanged.
  • The seat-side check-governed-merges.mjs --pr N reads no reviews (it never did, for the PATH limb either, and it cannot import the guard's derivation — the module cycle is measured in the file). It answers the SIZE question the way it answers the PATH question: over the line is exit 3 and the words name the two landings the queue leg then holds the PR to. On the same PR the two tools read one predicate; the queue additionally holds the approval record — the same relationship they have on a Tier H path today.

PM mechanism assumptions — what the tree said

  • Assumption 3 (the authorized-approval derivation is exported by check-governed-merges.mjs and imported by the guard): falsified. authorizedApprovalVerdict and GOVERNED_APPROVERS live in the guard; the guard imports the sibling at module scope, and the reverse edge (static or lazy) deadlocks (Detected unsettled top-level await, measured in both files' headers). There is still exactly ONE derivation — it stays in the guard; the sibling receives its result as data and re-derives nothing. No second copy was added.
  • Assumption 4 (protocol text): AGENTS.md class (c) stated the old rule and is rewritten (same three-line block, +1 line; ratchet ceiling 1116, now 1106). .claude/skills/pm-dispatch/SKILL.md:187 (「改动超 5000 行(含生成物)同换终局四件套」) and references/landing-operations.md:58 (「超 5000 行(含生成物)照 Tier H」) already route an oversized PR to the Tier H terminal, whose two landings line 189 / line 60 already spell (「授权批准 ⇒ 席位落地」, 「获授权批准后认领席落地」) — consistent, untouched, so no .claude/** file changes in this PR. scripts/pm/dispatch-gates.mjs's dispatch-time line said "lands only by a HUMAN MERGE" and is rewritten (its self-test pin updated).
  • Assumption 5 (--pr 20125 as a reading): NOT MEASURED from this container — the changed-files walk answered HTTP 403 on page 2 and the tool refused rather than answering on a subset (its documented behaviour). By construction it would answer exit 3 with the words naming both landings, and the queue leg would answer 0 on os-zhuang's approval on e4ead748 (the self-test replays exactly that shape).
  • Assumption 8 (unreadable review list): landed as exit 8, pinned in both scripts.

Grep table — 5,000 / 5000 / HUMAN_MERGE_LINE_THRESHOLD / size limb over scripts/pm/**, AGENTS.md, .claude/** at 8d1f7ab7

file verdict note
scripts/pm/check-governed-merges.mjs changed predicate, header, words, 13 new pins (battery floor 30 → 44)
scripts/pm/check-governed-queue-guard.mjs changed SIZE leg, header, words, 13 new pins + 3 rewritten (battery floor 30 → 54)
scripts/pm/dispatch-gates.mjs changed changedLineLines OVER text stated "lands only by a HUMAN MERGE"; its pin updated
AGENTS.md changed Multi-agent §7 class (c) stated "lands only by a human merge"
.claude/skills/pm-dispatch/SKILL.md consistent line 187 routes an oversized PR to the 四件套 terminal; line 189 names its two landings
.claude/skills/pm-dispatch/references/landing-operations.md consistent line 58 「照 Tier H」; line 60 names Tier H's two landings
scripts/pm/check-half-states.mjs consistent "a human merge or an authorized approval is the review record"; other hits are rate-limit numbers
scripts/pm/check-skill-line-ratchet.mjs unrelated a ceiling-ledger comment narrating the 2026-09-18 raise (history, not a rule statement)
scripts/pm/check-prior-rulings.mjs unrelated "5,000 comments" page cap
.claude/skills/pm-dispatch/references/platform-readings.md, references/rest-channel.md unrelated rate-limit quotas (5000/h)
board-snapshot.mjs, ci-failure.mjs, close-cards.mjs, fleet-token.mjs, issue-create.mjs, label-write.mjs, sweep-stale-finding.mjs, write-pace.mjs, check-dispatch-gates.mjs unrelated numeric coincidences (fixture ids, timeouts, quota numbers)

New pins

check-governed-merges.mjs — battery "⭐ the SIZE predicate": an authorized approval lifts (exceeds stays true, landsByHumanMerge false); threshold / strict comparison / inclusion unchanged; the words print approver, commit, objectstack#20153 and the seat landing; exit is the NOT-governed code; no approval / unapproved / unauthorized / unreadable / the generic reduction (no approvals field) each still fire; an approval under the line lifts nothing; a governed PATH and a FORK head are untouched by the lift; the sweep still lists an oversized landing; the not-lifted words name both landings.

check-governed-queue-guard.mjs — battery "⛔ #19036: the SIZE line at the queue": the governed leg's verdict object is REUSED (zero extra reads, group exits 0); #20125 replay — approval on the head and on an older commit both exit 0 with two reads; the block prints approver, commit, card and ruling; no / unauthorized / dismissed / superseded → 8 with the reason named; unreadable review list → 8 never 9; no review reader → 8; reviews are read only over the line (within PR: none; unreadable size: still 9, none); end to end governed clear + size lifted → 0, and with no approval → 8; sizeReading has four states; the authorized verdict carries approvals and the generic one does not; the guard's source spells no lift condition of its own; the remedy names both landings and keeps the bypass-rules option (#19344 battery unchanged and green).

Verification

Both self-tests green at head 52398a3b: check-governed-merges --self-test 454 assertions (was 441), check-governed-queue-guard --self-test 292 cases (was 279).

Reverse verification (ablation, committed state, scripts/ablation-replace.mjs, anchor hit 1 → 0, blob 4c5598c0d0c5 → c21c9c1a3338, restored to the HEAD blob with git diff HEAD empty, both legs): mutating the sibling's sizeLimbFires to ignore the lift reddens the guard's self-test (6 of 292 cases fail: reuse, #20125 replay, block words, end to end, four states) and the sibling's own (3 failures). Direction: 转红, as predicted.

Gate list from node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 52398a3b — 40 commands, all exit 0, reconciled with --ran (40 derived, 40 run, 0 NOT-MEASURED, 0 UNRUN; every line carries its exit code):

command exit
node scripts/check-ci-filter-parity.mjs 0
node scripts/check-closing-keyword-parity.mjs (+ --self-test) 0 / 0
node scripts/check-comment-mask-corpus.mjs 0
node scripts/check-declaration-mirrors.mjs (+ --self-test) 0 / 0
node scripts/check-scripts-symbol-anchors.mjs (+ --self-test) 0 / 0
node scripts/check-self-test-wired.mjs (+ --self-test) 0 / 0
node scripts/check-self-test-workflow-commands.mjs (+ --self-test) 0 / 0
node scripts/check-skills-token-ratchet.mjs (+ --self-test) 0 / 0
node scripts/check-whole-set-label-write.mjs (+ --self-test) 0 / 0
node scripts/pm/bare-root-worklist.mjs --self-test 0
node scripts/pm/check-governed-queue-guard.mjs --self-test 0
pnpm check:agent-test-spelling, check:bash32-floor, check:cli-command-ids, check:closing-target-claim, check:cross-package-test-inputs, check:declared-population-live, check:docs-audit-scope, check:driver-memory-census, check:entry-guard, check:gitlink-declared, check:nul-bytes, check:parse-guard 0 each
pnpm check:pm-dispatch-gates (894 s) 0
pnpm check:pm-governed-merges, check:pm-governed-prose, check:pm-skill-id-lint, check:pm-skill-ratchet, check:pnpm-filter-targets, check:ratchet-remedy-authority, check:refd-timer-probe, check:required-contexts, check:watch-hint-literal 0 each

Line budget: AGENTS.md 1105 → 1106 (ceiling 1116, headroom 10); SKILL.md and landing-operations.md unchanged (headroom 0 on both, untouched). check-skill-line-ratchet green.

Changeset: none — the diff touches scripts/pm/** and AGENTS.md only, nothing any released package ships; skip-changeset.

Acceptance notes

  • check-governed-merges.mjs --pr 20125 could not be read from this container (page 2 of the files walk answered HTTP 403 through the env-token channel; the tool refused rather than answering on a subset). Not a defect; the container's credential asymmetry.
  • The sweep's sizeCell does not annotate an oversized landing with the approval that lifted it (the card allows, does not require, that note); the sweep reads merged_by, not reviews, so adding it would add a review read per oversized row. Left as is.
  • check-skill-line-ratchet.mjs carries a ceiling-ledger comment narrating the 2026-09-18 ruling as "takes the same terminal"; it is history of a count, not a rule statement, and is untouched.

维护者速读(草稿)

改了什么:队列守卫的「超 5000 行」这一腿,现在和受管路径(Tier H)一样,承认你(或 GOVERNED_APPROVERS 里的账号)的 APPROVED 审查:批准过就放行,由认领席走队列落地;你直接合并这条路不变。阈值 5000、严格大于、含生成物,一个都没动;fork PR 不受此影响;事后审计照样把超 5000 行的落地列出来。

为什么改:你 2026-09-27 的裁决「所以阈值写死成 5000 行 , 维护者已经批准了就是可以合并。」——#20125 已获 os-zhuang 批准仍被队列两次踢出,就是这条旧规则(「只认人工合并」)造成的。

风险与代价(含回滚):代价是队列对每个超线的 PR 多读一次 review 列表(已被治理腿读过的直接复用,不重复读);批准后再推的提交不再被这一腿复审——与 Tier H 路径已接受的成本同形。review 列表读不到时按「未解除」拒收(退出码 8),不会误放。回滚 = revert 本 PR,两份脚本的自测各自变红,不会静默。

席位意见:(留空,由席位定稿)

你要做的:一个动作——本 PR 触及 AGENTS.md(Tier H),请 APPROVE 本 PR(或直接合并);批准后认领席走队列落地。


Generated by Claude Code

…ZE limb

The maintainer's 2026-09-27 ruling: the SIZE limb is lifted by an authorized
APPROVED review exactly as a Tier H path is. The queue guard's SIZE leg hands
the governed leg's own authorized-approval verdict to the sibling through
testVerdict([], { size, approval }); the lift itself lives in the sibling
(sizeLiftFrom / sizeLimbFires, read by landsByHumanMerge). Threshold, strict
comparison and generated-files inclusion unchanged; FORK limb unchanged; the
post-merge sweep still lists oversized landings. Protocol text updated where it
stated the human-merge-only rule.

Claude-Session: https://claude.ai/code/session_0148fenvVvyQV9HYxgVDQ33q
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/l documentation Improvements or additions to documentation labels Sep 27, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 27, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 52398a3b14f69bbcfc2341c3c43a090b5f7bdd0f

① Derived judgments

  • Governed rule text, AGENTS.md Multi-agent §7 class (c): "it lands only by a human merge, which is its review record" → "it lands the way a Tier H surface does: an authorized APPROVED review and then the owning seat, or a human merge". Correct: it is the maintainer's 2026-09-27 ruling, verbatim in the card (「所以阈值写死成 5000 行 , 维护者已经批准了就是可以合并。」); the class's trigger (over 5,000 changed lines, generated files included) is unchanged; no other line of the file moved (+2/−1 inside the same block; ratchet ceiling 1116, now 1106).
  • Accept set of the governed queue guard (fleet tooling, not a published contract): widened by exactly the ruled case — over the line AND an authorized APPROVED review (latest-decisive per account, on any commit; dismissed / superseded / unauthorized never count; an unreadable review list fails closed on exit 8). Every other refusal unchanged and pinned; the exit register unchanged (0 / 8 / 9). Not a Clause-②: yes change: no packages/spec, error-code ledger, public API or skills/** surface is touched.
  • Single derivation: the review-list reduction stays in the guard (authorizedApprovalVerdict, now also carrying approvals: [{ login, commitId }]); the sibling reads the verdict object (sizeLiftFrom) and derives nothing from reviews, pinned by a self-test that reads the guard's own source. Correct against the two-mechanisms rule the card cites.
  • Words: the SIZE block and the seat-side --pr words name both landings and cite the card; the 2026-09-18 ruling stays quoted beside the 2026-09-27 one.

② Semver level

None — no released package ships scripts/pm/** or AGENTS.md; skip-changeset is the declared form and matches the diff.

③ Boundary flags

Implemented-by: claude/issue-20153-size-limb-approval-lift
Reviewed-by: session_0148fenvVvyQV9HYxgVDQ33q

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)

改了什么:队列守卫的「超 5000 行」这一腿,现在和受管路径(Tier H)一样,承认 GOVERNED_APPROVERS 里账号的 APPROVED 审查:批准过就放行,由认领席走队列落地;你直接合并这条路不变。阈值 5000、严格大于、含生成物,一个都没动;fork PR 不受影响;事后审计照样把超 5000 行的落地列出来;退出码表没有新码(解除 ⇒ 0,无/非授权/已撤/被覆盖的批准 ⇒ 8,尺寸读不到 ⇒ 9,review 列表读不到 ⇒ 8 失败关闭)。

为什么改:你 2026-09-27 的裁决「所以阈值写死成 5000 行 , 维护者已经批准了就是可以合并。」——#20125 已获 os-zhuang 批准仍被队列两次踢出,就是旧规则「只认人工合并」造成的。

风险与代价(含回滚):队列对每个超线的 PR 多读一次 review 列表(治理腿已读过的直接复用,不重复读);批准后再推的提交不再被这一腿复审——与 Tier H 路径已接受的成本同形。回滚 = revert 本 PR,两份脚本的自测各自变红,不会静默。

席位意见:席位复核 ACCEPT(记录在 #20153)。两份自测席位在 head 52398a3b 上亲跑均绿(454 断言 / 292 用例),dev 的 40 条门禁全绿并已对账,消融验证按预期转红;唯一的批准推导仍在守卫内,姊妹脚本只读判定对象、不再推导。dev 提出的开放问题(席位侧 --pr 是否自己读 review 并打印解除)席位按 A 裁定:与 Tier H 路径今日的关系同形,不新开读取路径。本 PR 本身 571 行,只因 AGENTS.md 一句成 Tier H。建议批准。

你要做的:一个动作——本 PR 触及 AGENTS.md(Tier H),请 APPROVE 本 PR(或直接合并);批准后认领席走队列落地。


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 27, 2026 03:50
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 27, 2026
Merged via the queue into main with commit 1f33392 Sep 27, 2026
41 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-20153-size-limb-approval-lift branch September 27, 2026 04:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation needs-user-decision size/l skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

governed guard: an authorized APPROVED review lifts the >5000-line SIZE limb, as it already lifts Tier H paths

3 participants