Repository navigation
governed guard: an authorized APPROVED review lifts the >5000-line SIZE limb, as it already lifts Tier H paths #20153
Description
Activity
- addedpriority:p1High: required for production / M2High: required for production / M2and removed
on Sep 27, 2026 objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsClaim: PM loop round 3
Session:session_0148fenvVvyQV9HYxgVDQ33q
Account:os-tesla
Branch:claude/issue-20153-size-limb-approval-lift
Worktree:objectstack-issue-20153
Domain:domain:skills
Seat:domain:skills#1
File surface:scripts/pm/check-governed-merges.mjs,scripts/pm/check-governed-queue-guard.mjs,AGENTS.md,.claude/skills/pm-dispatch/SKILL.md,.claude/skills/pm-dispatch/references/landing-operations.md, plus only the files the card's Scope grep (5,000/5000/HUMAN_MERGE_LINE_THRESHOLD/size limbacrossscripts/pm/**,AGENTS.md,.claude/**) proves still state the old rule (stop on breach; explain in the report)
Container & model:M,mode:subagent,model: CONTRACT_REVIEW_TIER (the ceiling) — MANDATORY per this round's dispatch-gates --tier at 8d1f7ab7: ".claude/skills/pm-dispatch/SKILL.md ⇢ clause ① of the model-tiering ruling (narrowed to protocol semantics, 2026-08-20): the PM dispatch skill MAIN file is the lane's own operating protocol"
Clause-②: no
Thread-read: none
Serial constraints cleared: none — the 7 open objectstack PRs were scanned at claim time and none touches the five files above; the lane'spm:queueholds no sibling card;scripts/pm/os-verify-lock.sh --statusreads free with an empty queue (arrival depth 1 with this dev).
Ruling-ref: the card body's Provenance section (the maintainer, in chat with sessionsession_013RWUA7bNq5bRhehLPqXwMg, 2026-09-27), verbatim 「所以阈值写死成 5000 行 , 维护者已经批准了就是可以合并。」 and 「应该立一个 skills 卡片」 — no separate ruling comment exists on this card.
Tier: H — the PR touchesAGENTS.mdand.claude/**; it lands on an authorized APPROVED review (GOVERNED_APPROVERS) or the maintainer's own merge, per the rule in force until this card lands.
Clause-② reading: the card widens what the fleet's internal governed-queue guard accepts, under a maintainer ruling; it touches no published contract surface (packages/spec, the error-code ledger, the public API,skills/**), so no accept-set relaxation of a published contract is declared.
Generated by Claude Code
objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 20153, "status": "done", "branch": "claude/issue-20153-size-limb-approval-lift", "pr": "https://github.com/objectstack-ai/objectstack/pull/20159 (#20159, draft, head 52398a3b14f69bbcfc2341c3c43a090b5f7bdd0f, Tier H: touches AGENTS.md)", "session": "session_0148fenvVvyQV9HYxgVDQ33q", "premise_still_valid": true, "summary": "An authorized APPROVED review (GOVERNED_APPROVERS, latest-decisive, ANY commit; dismissed/superseded/unauthorized never count; unreadable list fails closed) now lifts the SIZE limb exactly as it lifts a Tier H path. The lift lives in check-governed-merges.mjs (sizeVerdict(size, approval) adds `lifted`; sizeLimbFires; landsByHumanMerge reads it) and the queue guard's SIZE leg hands in the governed leg's own authorizedApprovalVerdict object (reused when that leg already read the PR, else one review read of its own, only over the line) through testVerdict([], { size, approval }). Threshold 5000, strict comparison, generated-files inclusion, FORK limb, sweep listing, GOVERNED_APPROVERS, Tier S rule and the exit register are unchanged; exit 0 on the lift with approver, commit and objectstack#20153 printed; 8 for none/unauthorized/dismissed/superseded AND for an unreadable review list on an oversized PR; 9 stays size-unreadable. Protocol text rewritten in AGENTS.md class (c) and dispatch-gates.mjs's OVER line; SKILL.md:187 and landing-operations.md:58 were already consistent (they route to the Tier H terminal whose two landings lines 189/60 spell) and are untouched, so no .claude/** change.", "tests": "At head 52398a3b: `node scripts/pm/check-governed-merges.mjs --self-test` exit 0, 454 assertions (base 441; SIZE battery floor 30 -> 44 = exact count); `node scripts/pm/check-governed-queue-guard.mjs --self-test` exit 0, 292 cases (base 279; SIZE battery floor 30 -> 54 = exact count, measured with a 999 probe: 'registered 54 case(s)'). Gates: `dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 40 commands at 52398a3b; all 40 run in the foreground with exit codes captured before any pipe, all exit 0 (pnpm check:pm-dispatch-gates 894 s; check-comment-mask-corpus 66 s; the rest under 45 s); `--ran` with `:: exit N` lines: '40 derived, 40 run, 0 NOT-MEASURED, 0 UNRUN (a DERIVED zero — all 40 recorded an exit code and none of them is 3)'. Ablation (committed state, scripts/ablation-replace.mjs, anchor `return size?.exceeds === true && !size?.lifted;` hit 1 -> 0, blob 4c5598c0d0c5 -> c21c9c1a3338, mutant `return size?.exceeds === true; /* ABLATION */`): guard self-test RED 6 of 292 (reuse, #20125 replay head+older, block words, end-to-end, four states); sibling self-test RED 3 failures; both legs restored to the HEAD blob with `git diff HEAD` empty and on-disk counts anchor 1 / mutant 0 re-read after each leg. Direction 转红 as predicted. No build/dist involved (scripts run from source). NOT MEASURED: `check-governed-merges.mjs --pr 20125` live reading (page 2 of the files walk answered HTTP 403 through the env-token channel; the tool refused rather than answering on a subset).", "gates": [ "node scripts/check-ci-filter-parity.mjs :: exit 0", "node scripts/check-closing-keyword-parity.mjs :: exit 0", "node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0", "node scripts/check-comment-mask-corpus.mjs :: exit 0", "node scripts/check-declaration-mirrors.mjs :: exit 0", "node scripts/check-declaration-mirrors.mjs --self-test :: exit 0", "node scripts/check-scripts-symbol-anchors.mjs :: exit 0", "node scripts/check-scripts-symbol-anchors.mjs --self-test :: exit 0", "node scripts/check-self-test-wired.mjs :: exit 0", "node scripts/check-self-test-wired.mjs --self-test :: exit 0", "node scripts/check-self-test-workflow-commands.mjs :: exit 0", "node scripts/check-self-test-workflow-commands.mjs --self-test :: exit 0", "node scripts/check-skills-token-ratchet.mjs :: exit 0", "node scripts/check-skills-token-ratchet.mjs --self-test :: exit 0", "node scripts/check-whole-set-label-write.mjs :: exit 0", "node scripts/check-whole-set-label-write.mjs --self-test :: exit 0", "node scripts/pm/bare-root-worklist.mjs --self-test :: exit 0", "node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0", "pnpm check:agent-test-spelling :: exit 0", "pnpm check:bash32-floor :: exit 0", "pnpm check:cli-command-ids :: exit 0", "pnpm check:closing-target-claim :: exit 0", "pnpm check:cross-package-test-inputs :: exit 0", "pnpm check:declared-population-live :: exit 0", "pnpm check:docs-audit-scope :: exit 0", "pnpm check:driver-memory-census :: exit 0", "pnpm check:entry-guard :: exit 0", "pnpm check:gitlink-declared :: exit 0", "pnpm check:nul-bytes :: exit 0", "pnpm check:parse-guard :: exit 0", "pnpm check:pm-dispatch-gates :: exit 0 (894 s)", "pnpm check:pm-governed-merges :: exit 0", "pnpm check:pm-governed-prose :: exit 0", "pnpm check:pm-skill-id-lint :: exit 0", "pnpm check:pm-skill-ratchet :: exit 0", "pnpm check:pnpm-filter-targets :: exit 0", "pnpm check:ratchet-remedy-authority :: exit 0", "pnpm check:refd-timer-probe :: exit 0", "pnpm check:required-contexts :: exit 0", "pnpm check:watch-hint-literal :: exit 0", "dispatch-gates --ran reconciliation :: exit 0 (40 derived, 40 run, 0 NOT-MEASURED, 0 UNRUN)", "CI on PR #20159 :: in_progress (not waited for, per the dispatch)" ], "line_budget": "AGENTS.md 1105 -> 1106 (+1; ceiling 1116, headroom 11 -> 10; class (c) block rewritten in place, one extra wrapped line). .claude/skills/pm-dispatch/SKILL.md 319 -> 319 (untouched; headroom 0). references/landing-operations.md 101 -> 101 (untouched; headroom 0). check-skill-line-ratchet green.", "deviations": [ "PM assumption 3 falsified: the authorized-approval derivation (authorizedApprovalVerdict) and GOVERNED_APPROVERS live in check-governed-queue-guard.mjs, not in check-governed-merges.mjs; the guard imports the sibling at module scope and the reverse edge (static or lazy) deadlocks (measured in both headers). Kept ONE derivation in the guard; the sibling takes the verdict object as data through testVerdict(paths, { size, approval }) and re-derives nothing. No second copy added.", "PM assumption 4: SKILL.md:187 and landing-operations.md:58 needed no change (already 'Tier H terminal', whose two landings lines 189/60 spell); only AGENTS.md class (c) and dispatch-gates.mjs's changedLineLines OVER text stated 'lands only by a human merge' and were rewritten. Consequently the PR touches no .claude/** file (still Tier H via AGENTS.md).", "PM assumption 5: `--pr 20125` live reading NOT MEASURED (HTTP 403 on page 2 of the files walk from this container). By construction the seat-side --pr reads no reviews and answers exit 3 with words naming both landings; the queue leg's self-test replays #20125's shape (os-zhuang approved, 10764/999) and exits 0.", "PM assumption 8: an unreadable review list on an oversized PR refuses on exit 8 (not 9), pinned in both scripts; 9 stays 'size unreadable'. No new exit code.", "Dispatch expected the PR to touch .claude/**; it does not (see assumption 4). Card 'Scope' listed those two files; both are consistent and quoted in the PR table.", "The harness attribution reminder asked for a model-named Co-Authored-By trailer; AGENTS.md's model-free pair takes precedence (the pre-push hook refuses a model identifier), so the commit carries `Claude-Session:` + `Co-authored-by: Claude` only. Amended before the first push of that commit; nothing pushed was rewritten.", "Gate chunk 3 (items 23-32) exceeded the 600 s foreground cap because pnpm check:pm-dispatch-gates takes 894 s; the harness moved it to the background and I waited on its PID in the foreground with `tail --pid` (no polling), then read the exit file. All codes were captured by the runner before any pipe." ], "files_changed": [ "AGENTS.md (+2/-1 lines: Multi-agent discipline §7 class (c))", "scripts/pm/check-governed-merges.mjs (header section 'The SIZE limb's LIFT'; testVerdict approval input; sizeVerdict lifted/approvalState; sizeLiftFrom, sizeLimbFires, SIZE_LIFT_RULING, renderLiftApprovals exported; landsByHumanMerge; renderSizeLines; renderTestVerdict; 13 new pins; SIZE battery floor 44)", "scripts/pm/check-governed-queue-guard.mjs (header lift section replaces 'NO APPROVAL LIFTS THIS LIMB'; exit-table entry 8; authorizedApprovalVerdict.approvals; sizeReading 4 states; runSizeGuard fetchReviews+approvals reuse; renderSizeVerdict lifted/no-lift words and two-landing remedy; main wiring; 13 new + 3 rewritten pins; SIZE battery floor 54)", "scripts/pm/dispatch-gates.mjs (changedLineLines OVER text names both landings; its self-test pin updated)" ], "api_writes": "3 REST proxy writes, all through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (run 36290993088, PR #20159 draft); (2) label-write -> POST /issues/20159/labels {skip-changeset} + POST /issues/20159/assignees {os-tesla} (run 36291031520, read-back matches); (3) post-stamped -> POST /issues/20153/comments (this os-dev-report). Plus git push x2 (empty-branch probe, then 52398a3b) — not REST. Zero PATCH, zero MCP.", "mcp_calls": "0 — no MCP GitHub tool was called; all reads were single-card REST GETs (issue 20153, its comments, pulls?head=) and all writes went through scripts/pm/ via the relay.", "open_questions": [ { "question": "Should the seat-side `check-governed-merges.mjs --pr N` itself read the review list and print the lift (answering exit 0 on a lifted oversized PR), which requires moving authorizedApprovalVerdict + GOVERNED_APPROVERS into the sibling (re-exported from the guard) because the sibling cannot import the guard?", "options": [ "A (landed): --pr reads no reviews; over the line is exit 3 with words naming both landings; the queue leg holds the approval — the same relationship the two tools have on a Tier H path today. Zero moves of constants, one derivation stays where the card says it is.", "B: move the derivation into the sibling and let --pr read /pulls/N/reviews (one more GET), printing the lift seat-side; the guard re-exports the constant for check-half-states." ], "recommendation": "A, because — 实际业务需求: the seat already reads the approval on the PR before landing a Tier H path and does the same here (no seat asked for --pr to answer the approval); 项目长远合理性: the card's 'one derivation, imported, never restated' is met with the derivation left in the file that declares GOVERNED_APPROVERS, and B moves a ruled single-source constant to satisfy a convenience; 防 AI 犯错: A keeps --pr's exit 3 = 'may a seat arm this on green alone? no', so no reader learns a new meaning for 3, while B makes exit 0 depend on a review read that a 403 turns into a refusal on exit 1; 创业阶段不扩散: B is a new read path and a constant move for zero named pull. Revisit only if a seat reports landing on a stale seat-side reading." } ], "out_of_scope_findings": [ "carrier: none · noted, not filed — `check-governed-merges.mjs --pr 20125` cannot be read from this container (page 2 of the changed-files walk answers HTTP 403 on the env-token channel; the tool refuses correctly). Container credential asymmetry, not a defect in the tool.", "carrier: none · noted, not filed — the post-merge sweep's size row does not name the approval that lifted an oversized landing (the card allows, does not require it); the sweep reads merged_by, not reviews, so the note would cost a review read per oversized row." ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsACCEPT — objectstack#20153 · PR #20159 (draft, head
52398a3b) · reviewed by the skills seat,session_0148fenvVvyQV9HYxgVDQ33q(os-tesla), against GitHub at 2026-09-27T03:26Z.Checklist:
- Shape: draft, base
main, body first lineFixes #20153(the only closing keyword in the body; the other card numbers sit next to none). PR assignee os-tesla = the card's. Labelsskip-changeset(dev),size/l+documentation(bot). - Scope: 4 files —
AGENTS.md(+3/−2, Multi-agent §7 class (c)),scripts/pm/check-governed-merges.mjs(+168/−26),scripts/pm/check-governed-queue-guard.mjs(+295/−62),scripts/pm/dispatch-gates.mjs(+9/−6). Nothing undercontent/docs/releases/; no released package shipsscripts/pm/**orAGENTS.md⇒skip-changesetis the right form; no file outside the card. - Tests, the seat's own readings at head
52398a3b(a detached worktree of that commit):check-governed-merges.mjs --self-testexit 0, 454 assertions (base 441);check-governed-queue-guard.mjs --self-testexit 0, 292 cases (base 279);check-skill-line-ratchet.mjsgreen. The dev's gate list: 40 commands, 40/40 exit 0, reconciled with--ran(per-command table in the PR body). CI on this head at this reading: 19 success / 11 skipped / 3 in progress (Lint & Repo Gates, Type Check · workspace, Test Core 1/6) — the landing window reads them again. - Acceptance against the diff: the lift → exit 0 with approver, commit and
objectstack#20153printed (guard pins#20125-replay…LIFTS…exit-0-two-readsand the SIZE-block words); none / unauthorized / dismissed / superseded → 8 (one pin over all four); unreadable size → 9 unchanged (pin); an unreadable review list on an oversized PR → 8 (pinned in both scripts; the exit register gains no code). Threshold 5000, strict>, generated files included: pinned unchanged. FORK limb untouched (pin). The post-merge sweep still lists an oversized landing (pin).GOVERNED_APPROVERSunmoved. Reverse verification recorded: ablatingsizeLimbFiresreddens 6/292 + 3 — direction 转红. - One derivation: the guard's
authorizedApprovalVerdictstays the only reduction of a review list (its newapprovalsfield is the only thing that lifts); the sibling'ssizeLiftFromreads that verdict object and derives nothing from reviews; a guard self-test pin reads the guard's own source to prove it spells no lift condition. The card's "imported" wording was the PM's mechanism assumption 3, falsified by the measured module cycle (the sibling cannot import the guard) — the single-source property the card asks for holds. - Protocol text:
AGENTS.mdclass (c) anddispatch-gates.mjs's OVER line rewritten;SKILL.md:187–189 andlanding-operations.md:58–60 verified by the seat as already consistent (they route an oversized PR to the Tier H terminal whose two landings they spell) — untouched, agreed; the grep table in the PR body accounts for the other 16 hits. No.claude/**change; the PR is Tier H byAGENTS.mdalone (check-governed-merges.mjs --pr 20159: GOVERNED, tier H(人合), size 571 ≤ 5000). - Deviations accepted: (a)
--pr 20125NOT MEASURED from the container (HTTP 403 on page 2 of the files walk; the tool refuses on a subset — correct behaviour); the guard self-test replays feat!: retire the saved-report stack — /api/v1/reports, client.reports, IReportService, the reports capability, sys_saved_report / sys_report_schedule, @objectstack/plugin-reports #20125's shape. (b) Commit trailer perAGENTS.md(model-free), amended before its first push; nothing pushed was rewritten. - Open question, ruled by the seat (PM discretion — tooling, no product semantics or public contract): A. Seat-side
--pr Nkeeps reading no reviews and answers exit 3 naming both landings; the queue leg holds the approval — the same relationship the two tools have on a Tier H path today, and the card's "same predicate as the path leg" is met on that reading. B (the lift printed seat-side) stays available as its own card if a seat ever needs it. api_writes3 via the relay (pr_create, label-write, the report comment) + 2 pushes;mcp_calls0.
Tier H terminal on the PR, this round:
## Contract reviewrecord (governed rule text =AGENTS.md),needs-user-decision+ assignee, reviewers os-zhuang + hotlong, the 维护者速读 final. Lands on an authorized APPROVED review (then this seat through the queue) or the maintainer's hand.
Generated by Claude Code
- Shape: draft, base
objectstack-fleet commented
on Sep 27, 2026 ContributorAuthorMore actionsLanding paused at the seat's first landing act — PR #20159 (head
52398a3b) holds an authorized APPROVED review by os-zhuang (review 5328738072, on52398a3b, 2026-09-27T03:50Z), and os-zhuang flipped it ready at the same minute. CI on the head at this reading: 24 success / 15 skipped;Governed Surface Queue Guardre-running on the pull_request event since 2026-09-27T03:50Z;mergeable_state: blockedwhile it runs;needs-user-decisionstill on the PR.The seat's first landing act, written 2026-09-27T03:51Z:
node scripts/pm/label-write.mjs --repo objectstack-ai/objectstack --issue 20159 --remove needs-user-decisionwas refused by this session's auto-mode classifier ("judged this action dangerous", no explanation given). Per
references/landing-operations.mdB — 「落地遭分类器拒 ⇒ 停手、报维护者、卡上记命令与拒因;⛔ 不换拼法、不退回 ccr 绕过」 — the seat stops here: no label strip, noautomerge_enable, no other spelling of the same act.What remains, in order, once a maintainer clears it (strips the label, or tells the seat to proceed): relay
automerge_enable(the PR is already ready,pr_readyis moot) → two readings for MERGED → closeout of this card (Fixescloses it; thenpm:dispatchedoff, assignee cleared). The maintainer's own merge is the other landing; after it, the seat's closeout is the only remaining act. Reported in the seat's chat and on the seat post.
Generated by Claude Code
- added a commit that references this issue
on Sep 28, 2026
Ruled: maintainer 「所以阈值写死成 5000 行 , 维护者已经批准了就是可以合并。」 and 「应该立一个 skills 卡片」 · chat with session
session_013RWUA7bNq5bRhehLPqXwMg, 2026-09-27Provenance
session_013RWUA7bNq5bRhehLPqXwMg, 2026-09-27.CI_FAILURE. The cause wasGoverned Surface Queue Guardexit 8, the SIZE leg: about 11.5k changed lines, over 5,000, althoughos-zhuang(inGOVERNED_APPROVERS) had approved it. The Tier H path leg was already satisfied by that approval.The rule today
scripts/pm/check-governed-queue-guard.mjs, header section "NO APPROVAL LIFTS THIS LIMB":So a PR with more than 5,000 changed lines can only land through the maintainer's bypass-rules merge button, even after an authorized approval. That button skips the merge queue's speculative build on the latest
main.The ruling this card implements
An authorized APPROVED review lifts the SIZE limb exactly as it lifts a Tier H path. "Authorized" means an account in
GOVERNED_APPROVERS. After the approval, the owning seat lands the PR through the queue ("席位落地"), under the same predicate as the path leg:The maintainer's direct merge stays the other landing, unchanged.
Scope
scripts/pm/check-governed-merges.mjs: the SIZE predicate, its header section "The SIZE predicate",landsByHumanMerge(or the verdict it reads), and the self-tests that pin "no approval lifts size". The threshold (5,000), the strict>and "generated files included" are unchanged.scripts/pm/check-governed-queue-guard.mjs:skills/*/references/_index.mdis generator-owned (gen:skill-refs) yet sits inside theskills/**governed-merge fence — every spec PR touching an indexed headline is forced to carry a governed-surface file #11705 two-mechanisms rule);AGENTS.md(class (c), "lands only by a human merge");.claude/skills/pm-dispatch/SKILL.md:187;.claude/skills/pm-dispatch/references/landing-operations.md:58;5,000/5000/HUMAN_MERGE_LINE_THRESHOLD/size limbacrossscripts/pm/**,AGENTS.md,.claude/**). Keep the skill line ratchet (check-skill-line-ratchet.mjs) green.Out of scope
GOVERNED_APPROVERS, to the Tier S rule, or to branch protection / rulesets (the maintainer's).Acceptance
merge_groupwith one PR over 5,000 changed lines:check-governed-merges.mjs --pr Nagrees with the queue leg on the same PR.--self-testof both scripts passes, with new pins for the lift and for each non-lift case above.os-zhuang) passes the guard through the queue with no new approval.Landing
This card's own PR touches
AGENTS.mdand.claude/**, so it is Tier H. It waits for the maintainer's hand or an authorized APPROVED review, per the current rule.Generated by Claude Code