Repository navigation
finding: a stacked PR series has no model in this repo's tooling — three costs measured end-to-end on the #14478 six-card stack #16149
Description
Filed bare for triage by the domain:spec execution seat (session_01G4138K1EG7kQ81FNba5Kp4) after the #14478 stack landed on main at e9fcd6bbd (2026-09-06T03:17Z). Observation, not a graded defect — no fix proposed, no domain:* set, no pm:queue.
The stack was six cards deep (#15676 → #15682, PRs #15814 · #15837 · #15906 · #15938 · #15988 · #16022), each branched off the one below it, landing on a shared trunk branch and then to main as PR #15626. It worked, but three separate pieces of tooling turned out to have no representation of "this PR is stacked on another PR", and each cost real work. All three are measurements from that campaign, not predictions.
1. check:adr-0087-registration — already-registered is base-relative, and a stacked card has two bases
The gate's own header states the rule:
already-registered— every named id must resolve at HEAD and already exist at the merge base. If the id is new in this diff the honest disposition isregistered, and the two cannot be confused because base decides.
Card 6/6 renamed a key already covered by a conversion card 5/6 registers. So:
| base | is turso-config-timeout-to-timeout-ms there? |
honest disposition |
|---|---|---|
| card 6/6's own base (card 5/6's head) | yes | already-registered — exit 0 |
origin/main |
no | registered — anything else fires R5, severity 3 |
Neither card is wrong. The two base levels demand contradictory dispositions, and R5 consults only the ids this diff adds, with no cross-reference to a sibling changeset carrying registered in the same eventual merge. Writing registered on card 6/6 would have fired R4 against its own base instead.
The workaround that shipped: land all six cards on the trunk, then edit the disposition to registered on the trunk before it merged to main. Verified there — exit 0, .changeset/driver-turso-config-timeout-ms.md [BREAKING+bang] registered turso-config-timeout-to-timeout-ms (new here: …).
Two traps found while pre-verifying that edit, worth recording whether or not this is ever fixed:
- The gate reads the changeset from the committed diff, not the working tree. An uncommitted edit returns the identical finding, so it reads as "the fix does not work".
- Trailing prose on the marker line is parsed as further ids. Keeping the explanatory sentence inline produced "29 of those id(s) do not exist in the ADR-0087 registries at HEAD: —, that, protocol-18, conversion, added, by, …". The
not-required (…)form tolerates prose only because the parentheses delimit the ids.
2. Squash-only × stacked ⇒ one repair lap per descendant, cumulative
Merge commits are refused at the API level:
PUT /repos/objectstack-ai/objectstack/pulls/15906/merge (merge_method: merge)
→ 405 Merge commits are not allowed on this repository
and main carries 0 merge commits in its last 154 (control: the same --merges query does find one on a feature branch, so the zero is a reading).
A squash keeps the content and destroys the ancestry link, so every descendant's merge base rewinds past everything already landed. Measured after card 2/6 landed:
git merge-base --is-ancestor dcd1be0db 43cc4659a → exit 1 (2/6's head is NOT in the trunk's history)
git merge-base 43cc4659a adad660a1 → 140e0b266 (before cards 1/6 AND 2/6)
The descendant then re-applies content the trunk already holds and collides. Three repair laps were paid — cards 3/6, 4/6 and 6/6 — each a merge, a hand resolution and a regeneration pass. The conflicts were benign in shape but not free: card 4/6's four conflicts were all one prose correction made after it forked, and its side was a purely inherited stale snapshot (blobs byte-identical to its fork point).
⭐ The generalisation, which is what makes this worth a card: the cost is not per-stack, it is per-descendant, and it recurs on every landing. A six-deep stack pays it five times if nothing changes.
3. Heavy CI never runs on a stacked PR at all
lint.yml and ci.yml both declare:
on:
pull_request:
branches:
- mainA PR based on a feature branch triggers neither, so none of the six required contexts reports on any stacked head. Measured across this whole stack: every card PR showed 8–11 light checks (Auto Label, Check Changeset, PR Size, docs drift, …) and zero of Lint & Repo Gates, TypeScript Type Check, Test Core, Build Core, Dogfood Regression Gate, Temporal Conformance.
Consequence: a stack's first real signal arrives only at the trunk PR, after every card is written, reviewed and merged. Six cards' worth of work was verified by local runs quoted into PR bodies — which is a discipline that worked here, but it is a discipline, not a gate. On the trunk PR the real run came back 35/35 green on the first try; that is a fact about this stack's care, not about the arrangement's safety.
Prior art in this repo
#12933 is the same family through a different mechanism: GitHub's speculative queue stacking made merge-queue-triage count one deterministic failure as N distinct victim PRs, because the tooling had no notion that the victims were one stack. That card's phrasing applies here too — the count (or the disposition, or the trigger) is systematically wrong in a knowable, mechanically detectable way, and every reader re-derives it by hand.
For triage
Deliberately not split into three cards: the three costs were measured on one campaign and a reader deciding whether this repo should support stacked series needs them together. Splitting is triage's call. Each has a different owner and a different kind of fix — a gate rule, a repository setting or policy, and a workflow trigger — and it is entirely reasonable to grade them differently, including grading some or all of them "won't fix, stacks are rare enough".
Activity
os-zhuang commentedon Sep 6, 2026
分诊:
domain:devx/enhancement+tooling+finding/needs-user-decision/priority:p3⛔
needs-user-decision不与pm:*并存(先例 #15854 / #15617 / #15542),故不挂pm:queue。落点核实(
origin/main,本轮实读)第 3 项——本席可以在源码上直接复核,且成立:
两个工作流都把
pull_request限定到branches: [main]。⇒ 一个基于 feature 分支的 PR 两者都不触发,卡片对第 3 项的机制描述逐字成立。check:adr-0087-registration的双基线矛盾、405 Merge commits are not allowed、git merge-base --is-ancestor的 exit 1、以及三次修复回合的成本,都是该 campaign 的现场实测,需要那次 stack 的分支才能复现,本容器的克隆是浅克隆(本 lane 纪律⑫:任何git log历史查询在此不构成历史读数)。⛔ 不要把本席对第 3 项的核对当成对第 1、2 项的复现继承下去。✅ 但卡片第 2 项自己带了活控制,符合本 lane 纪律②:"
maincarries 0 merge commits in its last 154 (control: the same--mergesquery does find one on a feature branch, so the zero is a reading)" ——零命中配同一次读取里的正控制,⇒ 该零是读数。这一条本席背书。为什么挂决定箱,而不是拆成三张卡直接排期
因为卡片自己把待答问题写成了一个策略问题,而不是三个技术问题:
⇒ 「本仓是否要支持 stacked PR series」这个前置问题不答,三项的排期都无从谈起:答"不支持",三项全部降为"记录在案,遇到时按本卡的 workaround 手动处理";答"支持",三项各自有明确且互不相同的 owner。⛔ 本席不裁决(本会话
claude-opus-5,CONTRACT_REVIEW_TIER硬门要求 fable)。四facet
① 事实(第 3 项已复核,第 1/2 项为现场实测)
#14478 的六卡 stack(#15676 → #15682,PR #15814 · #15837 · #15906 · #15938 · #15988 · #16022,经 trunk 分支以 PR #15626 落
main,e9fcd6bbd@ 2026-09-06T03:17Z)成功落地,但三处工具链对"这个 PR 叠在另一个 PR 上"没有任何表示,各自产生了实际工作量:check:adr-0087-registration的already-registered是相对基线的,而 stacked 卡有两条基线,同一处置在两条基线下互相矛盾(对自身 base 应写already-registered,对origin/main应写registered;写错任一条分别触发 R5 严重度 3 或 R4)。Lint & Repo Gates/TypeScript Type Check/Test Core/Build Core/Dogfood Regression Gate/Temporal Conformance)零个报告。第一次真实信号只在 trunk PR 到达——在六张卡全部写完、评审完、合并完之后。② 分叉
lint.yml/ci.yml的pull_request触发器加上 feature 分支。③ 各支的代价
④ 需要裁决者提供的东西
一句话:本仓是否把 stacked PR series 当作受支持的工作形态? 答"是"⇒ 走 B 并按下面的拆分排期;答"否"⇒ 走 A,但请单独回答第 3 项(见下)。
⭐ 本席的拆分建议(卡片明说拆分是 triage 的活)
建议拆成 1 + 2,而不是 3:
pull_request: branches: [main]意味着任何基于 feature 分支的 PR 都拿不到六个必需上下文——这不是 stack 特有的,stack 只是把它暴露出来的场景。卡片自己写得很克制:"Six cards' worth of work was verified by local runs quoted into PR bodies — which is a discipline that worked here, but it is a discipline, not a gate." ⇒ "一条纪律,不是一道门",正是本 lane 一整天在追的那个失败类的另一种说法。而 trunk PR 首轮 35/35 全绿,卡片诚实地指出那 "is a fact about this stack's care, not about the arrangement's safety" ——本席原样背书这句自我限定。⛔ 本席不代为拆卡:拆卡会新建卡片,而本轮的纪律是先清完既有裸卡;且第 3 项的粒度(只加触发器 vs 同时处理 merge_group 与 concurrency 的相互作用)需要 CI owner 判断。建议由承接席或 CI lane 在取卡时执行拆分,并在本卡上回链新卡号。
lint.yml:12-20与ci.yml:9-15的那两段注释——它们记录了 merge_group 触发器与队列必需检查之间的耦合(ci.yml:12-15:"Every workflow that produces a branch-protection-required check MUST carry this trigger, or queue builds wait forever on a check that never reports"),以及lint.yml:16起那段 MEASURED 2026-08-25 (#12211) 的否定结果。放宽pull_request的分支面会显著增加 runner 用量,且与ci.yml:17起的 concurrency 取消策略相互作用。⛔ 不是一行改动。定级理由
domain:devx:三项落点分别是scripts/的门、仓库合并策略、.github/workflows/——全部在domain:devx的 lane 内。enhancement而非bug:main 上没有东西是假的——三处工具各自在其被设计的场景下都正确工作,只是对 stacked 这个形态没有表示。卡片自己的定性 "Observation, not a graded defect" 本席采纳。bug。finding:整卡是一次 campaign 的端到端实测,带控制(第 2 项的--merges正控制)、带日期、带具体 sha 与 PR 号。与 #12933 的关系
卡片说它是"同一族、不同机制"(GitHub 的推测式队列堆叠让⚠️ 但裁决者应当把两张一起看:若答案是"本仓不支持 stacked series",那么 #12933 的那个错误计数就是一个不该存在的形态的产物,处置会随之改变。
merge-queue-triage把一次确定性失败记成 N 个不同的受害 PR,因为工具没有"这些受害者是同一个 stack"的概念)。本席认同并背书卡片引用的那句概括——the count (or the disposition, or the trigger) is systematically wrong in a knowable, mechanically detectable way, and every reader re-derives it by hand——它同时描述了本卡的三项。⛔ 不合并:#12933 的机制在队列里,本卡的在 PR 与门上。✅ 最后记一笔:卡片明确写下它不主张的东西——"that stacking was the wrong choice for #14478. Six cards over one contract surface, each independently reviewable, is what the maintainer ruled and it produced a clean landing." ⭐ 把"我测到了成本"与"我认为当初的决定错了"分开,是本席希望被复制的填卡纪律。
⛔ 本席为 triage 席位:不认领、不派单、不写码、不合并、不裁决 decision-box。
Generated by Claude Code
os-zhuang commentedon Sep 7, 2026
Ruling recorded — option C: fix item 3 on its own; items 1–2 recorded as "stacked series are not a supported form" (director seat, decision batch #66, 2026-09-07)
Maintainer reply, verbatim: 「同意」 (all five batch #66 recommendations adopted).
Ruling.
lint.yml/ci.ymlpull_requesttriggers are limited tobranches: [main], so six required contexts report nothing on such PRs (item 3 of #16149) #16482 (domain:devx, p2,bug): widen the heavy workflows'pull_requesttrigger, honouring themerge_groupcoupling and the concurrency policy documented inci.yml:12-17andlint.yml:16, and recording the runner-cost delta before landing.registeredon the trunk before it merges; expect and pay the rebase laps). No gate rule and no merge-policy change is made for them.Execution (this card, skills seat, governed PR): one AGENTS.md paragraph stating the above, pointing at this card for the measured costs and workarounds. #12933's mis-count of speculative-queue stacking is a separate mechanism and is unaffected.
Labels:
needs-user-decision→pm:queue; lanedomain:devx→domain:skills(the remaining work is the AGENTS.md paragraph). Ledger on #12708 (batch #66).Generated by Claude Code
hotlong commentedon Sep 8, 2026
Claim: PM loop round 1 — flight B: ruling C's AGENTS.md paragraph — stacked PR series are not a supported working form; item 3 lives in #16482
Session:
session_01P58euzUXCVJNwmhuPC9DXYBranch:
claude/issue-16149-stacked-series-not-supportedWorktree:
objectstack-issue-16149Domain:
domain:skillsFile surface:
AGENTS.md(one paragraph added, fold-paid inside the same file at 1068/1068; ⛔ no gate, workflow or merge-policy change) (stop on breach; explain in the report)Container & model:
S (one governed paragraph plus its ratchet payment),mode:subagent,model: opus — --tier output at 02:40Z: "no path-derived mandate … floor sonnet · default opus · ceiling fable"; default judgement tier: a ruling implementation on the instruction architecture file, with a fold-payment judgementClause-②: no
Thread-read: 5570948653
Serial constraints cleared:
AGENTS.mdwas held by devx PR #16573 (#16479), MERGED 2026-09-08T02:13Z as5022924— the serial queue released this fire; #16633 (the footer sentence, same file) is queued BEHIND this card, fold-or-serial answered SERIAL on the seat post (different defect shape and fix); open objectstack PRs at 02:39Z (15) — none namesAGENTS.mdby title; no lane in-flight claim; noclaude/issue-16149-*ref at 02:32Z; no H17 hold trigger file hit; verify lock free at 02:39Z. Governed ⇒ draft only at the governed terminal.Generated by Claude Code
hotlong commentedon Sep 8, 2026
os-dev-report
{ "issue": 16149, "status": "done", "branch": "claude/issue-16149-stacked-series-not-supported", "pr": "https://github.com/objectstack-ai/objectstack/pull/16743", "premise_still_valid": true, "summary": "Ruling C's execution item landed as one AGENTS.md paragraph in Multi-agent working discipline, as an indented continuation of numbered rule 2 (the rule that already reads 'Branch off main') — that is the sentence the ruling qualifies. The paragraph declares stacked PR series unsupported, states each of the three tooling blind spots in one mechanism clause, gives the trunk-branch route with both recorded workarounds (correct the trunk's disposition to registered before it merges; pay the rebase laps), and closes with the boundary that no gate or merge-policy change is made. No gate, workflow or merge policy was touched; item 3 (card #16482, domain:devx) untouched. PR is draft and stays draft: governed surface, exit 3 GOVERNED. Claim verified before any edit — newest Claim: comment 5578356540 names this branch and this session; assignee never written.", "tests": "No build/test applies — the diff is one Markdown file in a private root package, so no package closure, no typecheck target, no vitest target; the verify lock was never needed and never taken. Gate union re-run at final commit 7a233b9b on a clean tree, all exit 0: node scripts/check-closing-keyword-parity.mjs=0; --self-test=0; node scripts/check-comment-mask-corpus.mjs=0; check:agent-test-spelling=0; check:docs-audit-scope=0; check:driver-memory-census=0; check:nul-bytes=0; check:pm-governed-merges=0; check:pm-governed-prose=0; check:pm-skill-id-lint=0; check:pm-skill-ratchet=0; check:refd-timer-probe=0; check:required-contexts=0; check:watch-hint-literal=0. Verdict lines: 'check-nul-bytes: OK (scanned 8270 text file(s) -- 8270 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).'; 'check-skill-id-lint: 26 file(s) clean (pattern /#[0-9]{3,}/g).'; 'check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfaces (docs/adr/** . .claude/** . skills/** . AGENTS.md . CLAUDE.md) and claim no others.' Reconciliation: 'dispatch-gates --ran: 14 derived famil(ies) accounted for — 14 run, 0 NOT-MEASURED.' Governance predicate: node scripts/pm/check-governed-merges.mjs --test AGENTS.md EXIT=3, 'GOVERNED — a human merge is the review record for this PR.' Lint narrowing PROVEN not skipped, three readings: (1) population from eslint.config.mjs — every files: block globs {ts,tsx,mts,cts,js,jsx,mjs,cjs}, no markdown block; (2) count from --format json — one entry, errorCount 0, single warning 'File ignored because no matching configuration was supplied.'; (3) invariance — the one touched path is outside eslint's population and type-aware linting is scoped to the TS globs, so no untouched file's verdict can move. Merge-tree vs origin/main 1ea349f0: exit 0, no conflicted paths; git check-attr merge -- AGENTS.md = 'merge: unspecified', so no os-regen driver ran and that exit 0 is a real textual reading, not a deferral. No ablation applies (documentation change, no gate or code behaviour added). Control-byte self-scan of AGENTS.md beyond the gate: grep -naP over the control ranges, zero hits.", "line_budget": "AGENTS.md before 1068, after 1068, net 0. Ratchet verdict at 7a233b9b: 'check-skill-line-ratchet: AGENTS.md is 1068 lines (ceiling 1068; headroom 0).' and 'check-skill-line-ratchet: AGENTS.md: widest table row is 768 bytes (pin 768; headroom 0).' Ceiling NOT raised. Paid by deleting content, not by re-wrapping: the fenced ADR-0087 marker block in Post-Task Checklist item 3 plus its surrounding prose, 10 lines rewritten to 3, funding the 7-line paragraph (6 content lines + 1 blank). Survivor check for every cut line — the four adr-0087 marker spellings still live in FIXIT in scripts/check-adr-0087-registration.mjs, which prints them on every failure and prints SEVEN categories where AGENTS.md listed four (runtime-interface-only and type-surface-only were missing); the category semantics live in ADR-0087's addendum of 2026-08-13, named by that same FIXIT output; and the three load-bearing facts (add exactly one marker, the gate name, the CI step name) were KEPT in place. The cut copy was drifted and under-reporting inside a paragraph whose own closing sentence already said the gate's output is the authority, so the deletion removes a misleading duplicate rather than a rule.", "gates": "14/14 derived families exit 0 at 7a233b9b; list re-derived in-worktree with 'node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack' (no path args, merge-base derived) and it matched the dispatch's 14 exactly — no family added, none dropped. --ran reconciliation: 14 derived, 14 run, 0 NOT-MEASURED, 0 UNRUN. Plus governed predicate EXIT=3. Full command/exit/verdict detail is in the tests field.", "files_changed": "AGENTS.md (only). +10 / -10, 1 file, 1 commit 7a233b9b. No changeset: skip-changeset label applied, justified by measurement — no non-private package lists AGENTS.md in its files[], and the root package is private:true, so nothing publishes.", "deviations": [ "RULING-VS-GATE, declared: the ruling says the paragraph should point 'at this card for the measured costs and workarounds'. That form is mechanically unavailable in this file — AGENTS.md is in check-skill-id-lint's scan set (EXTRA_FILES) with pattern /#[0-9]{3,}/g, so a five-digit card number there is a hard red. Ran the gate and read its source rather than guessing, per the dispatch. Resolved the way that gate's own header prescribes: 'a rule's provenance lives in the PR that landed it' — the card pointer lives in the PR body (Fixes #16149) and the paragraph carries the lesson self-contained (failure mode + discipline + boundary), one mechanism clause per cost, no numbers restated. PM assumption 2 therefore resolved to the RESTRICTED branch.", "DISPATCH ERRATUM: the order asked for 'node scripts/pm/check-governed-queue-guard.mjs --test AGENTS.md' expecting exit 3 GOVERNED. That script has no --test PATHS mode; it reads GITHUB_EVENT_PATH only and correctly refuses with exit 1 when absent ('could not look must never exit 0'). The --test predicate belongs to the sibling scripts/pm/check-governed-merges.mjs, whose header states exit 3 is deliberately the same code. Ran the correct script: EXIT=3 GOVERNED. Not a defect in either script.", "BASE MOVED: dispatch quoted origin/main 5e53d73; on my own fetch it had advanced to 1ea349f0. Worktree branched from 1ea349f0, all readings taken there.", "CHANNEL: repo-scoped REST is 403 for this seat ('GitHub access is not enabled for this session'); /rate_limit reads 15000/hr, so the credential is live and repo-scoped writes are gated, not exhausted. Card body read via the zero-quota public payload channel; comments, PR create, labels and this report via MCP. Label write used the documented fallback (read current -> union -> whole-group write -> comparative read-back) because the add-only REST endpoint is unreachable; read-back returned exactly union(size/s, skip-changeset) with nothing stripped and draft still true." ], "mcp_calls": "8 — issue_read(get_comments), create_pull_request, pull_request_read(get), issue_read(get_labels, errored: does not resolve PR numbers), list_pull_requests(labels read), issue_write(labels), list_pull_requests(label read-back), add_issue_comment(this report)", "open_questions": [], "out_of_scope_findings": [ "repaired here as the fold payment, no card needed: the AGENTS.md ADR-0087 marker block listed 4 of the gate's 7 disposition categories, omitting runtime-interface-only and type-surface-only — an author trusting it would have picked from an under-reported set. Same file, same gate family, mechanical fix, no new verification surface, so it met the bounded-in-place criteria; declared in the PR body with the survivor check.", "noted, not filed: scripts/pm/check-governed-queue-guard.mjs has no --test PATHS mode (see deviations). Successor: the PM, who owns the dispatch template that named it. Not a defect — the script's refusal-without-event-payload is its documented correct behaviour, so it is not (a), (b) or (c).", "noted, not filed: no other observation. Deliberately did not touch card #16633 (same file, footer sentence), which the claim comment records as queued serially behind this one." ] }Generated by Claude Code
hotlong commentedon Sep 8, 2026
os-dev-report
{ "issue": 16149, "status": "done", "round": "patch round 2 (REWORK-lite) — incremental over comment 5578512590", "branch": "claude/issue-16149-stacked-series-not-supported", "pr": "https://github.com/objectstack-ai/objectstack/pull/16743", "premise_still_valid": true, "head": "1c56734885aa4613ae19ad4c147030822d76f609 (short 1c5673488), was 7a233b9be; merge base now 7c12e475e", "summary": "Seat review accepted and applied: the heavy-CI clause (card item 3) is removed from the AGENTS.md paragraph. The ruling grades item 3 as 'a defect independent of stacking' and splits it to its own devx card, so stating it as an inherent property of stacking both mis-grades a defect as an accepted cost and goes false the moment that card lands. The paragraph now carries only the two structural costs the ruling assigned here: squash landing destroys the ancestry link so every descendant pays a rebuild lap per landing; and a breaking changeset's ADR-0087 disposition is base-relative so a stacked card's two bases demand contradictory markers. No number pointing at the devx card was added (id-lint), and no hedged substitute such as 'CI does not run on these yet' was used — that wording has the same expiry date. Three commits appended, no amend, no force-push. PR still draft, never flipped ready, never enqueued, never armed, no review requested.", "commits_appended": [ "6d5ba7fce merge origin/main (clean; only scripts/check-regen-pending.mjs arrived; AGENTS.md untouched by others between 1ea349f0e and 7c12e475e)", "82f067290 drop the heavy-CI clause from the stacked-series paragraph", "1c5673488 keep the stacked-series paragraph inside the 120-byte budget" ], "line_budget": "AGENTS.md 1068 -> 1067, net -1. Verdict at 1c5673488: 'check-skill-line-ratchet: AGENTS.md is 1067 lines (ceiling 1068; headroom 1).' and 'check-skill-line-ratchet: AGENTS.md: widest table row is 768 bytes (pin 768; headroom 0).' Nothing was restored to pad the count back to 1068 — the ADR-0087 fold payment from round 1 stands untouched, and the ratchet is a cap so a net decrease is legal. NEW FINDING, reported because it is a distinct check the round-1 report did not name: check:pm-skill-ratchet ALSO enforces a per-LINE 120-BYTE budget beside the per-file line ceiling. The first reflow of the shortened paragraph tripped it by one byte — '✗ check-skill-line-ratchet: AGENTS.md has 1 line(s) over the 120-byte budget: L469 (121B).' Fixed in 1c5673488 by rewrapping to five lines, each under budget (118/119/120/119/112 B), shortening the closing boundary to 'No gate or merge-policy change is made for it' to avoid a 6-byte orphan line. Whole-file rescan: 14 lines remain over 120B, all of them tables or a blockquote, i.e. structurally exempt by shape, and none of them mine.", "gates": "14/14 exit 0 at 1c5673488 on a clean tree. List re-derived TWICE. First derivation warned 'STALE TREE — 1 file(s) it derives from CHANGED': scripts/check-regen-pending.mjs had moved on origin/main, and since that file's new copy literally contains the string AGENTS.md the derivation could have shifted. Rather than reason about it I merged origin/main and re-derived from a current tree: no stale warning, merge base 7c12e475e, and the derived list came back byte-identical to the dispatch's 14. Reconciliation: 'dispatch-gates --ran: 14 derived famil(ies) accounted for — 14 run, 0 NOT-MEASURED.' (14 derived, 14 run, 0 UNRUN). Commands and exits: node scripts/check-closing-keyword-parity.mjs=0; --self-test=0; node scripts/check-comment-mask-corpus.mjs=0; check:agent-test-spelling=0; check:docs-audit-scope=0; check:driver-memory-census=0; check:nul-bytes=0; check:pm-governed-merges=0; check:pm-governed-prose=0; check:pm-skill-id-lint=0; check:pm-skill-ratchet=0; check:refd-timer-probe=0; check:required-contexts=0; check:watch-hint-literal=0. Verdicts: 'check-skill-id-lint: 26 file(s) clean (pattern /#[0-9]{3,}/g).'; 'check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfaces ... and claim no others.' Governance predicate: node scripts/pm/check-governed-merges.mjs --test AGENTS.md EXIT=3, 'GOVERNED — a human merge is the review record for this PR.' No os-regen debt outstanding after the merge (git-dir os-regen-pending absent). Control-byte self-scan of AGENTS.md: zero hits.", "files_changed": "AGENTS.md only (plus scripts/check-regen-pending.mjs arriving via the origin/main merge, not authored here). Branch delta vs merge base 7c12e475e is AGENTS.md alone.", "pr_body": "Rewritten and read back in full to the tail. 'three tooling blind spots' -> 'two structural costs'; new section 'Why item 3 is not in the paragraph' stating the ruling's grading and the rot argument; 维护者速读(草稿) gains a matching 为什么第三条没写进来 paragraph; measurements updated to 1c5673488 / 1067 lines / merge base 7c12e475e, plus the byte-budget finding.", "deviations": [ "FOOTER, measured: the documented edit behaviour is that the platform appends a bare footer block under an edited body. It did NOT on this edit (issue_write body update): the body now ends at the last prose line with no footer block at all. Not re-sending a footer — re-sending is the documented double-footer failure mode. Durable attribution is carried by the commit trailers (Claude-Session on each commit).", "LABELS: auto-labeler added 'documentation' between rounds (another actor). Read-back after the body edit: ['documentation','size/s','skip-changeset'] — my skip-changeset survived, nothing of mine stripped, draft still true. Not corrected, per the do-not-touch-other-actors' state rule.", "BODY EDIT CHANNEL: used issue_write (issues API) rather than update_pull_request, because update_pull_request sends the draft bit on every call whether or not you pass it — the documented way governed drafts have been published into the merge queue by accident. issue_write carries no draft field. Read-back confirms draft:true.", "Round-1 deviations still stand: the id-lint constraint forbidding a card number in AGENTS.md; the dispatch's erratum naming check-governed-queue-guard.mjs instead of check-governed-merges.mjs for --test; REST 403 for this seat with MCP as the write channel." ], "mcp_calls": "12 cumulative (round 1: 8; round 2: issue_write(body), list_pull_requests(labels/draft), list_pull_requests(body read-back), add_issue_comment(this report))", "open_questions": [], "out_of_scope_findings": [ "noted, not filed: check:pm-skill-ratchet's per-line 120-byte budget is enforced but is not mentioned in AGENTS.md's own text, so an author editing a ratcheted file meets it only as a gate failure. Successor: whoever next edits a ratcheted instruction file — which is the same small set of seats. Not filed as a defect: the gate's failure message is complete and self-explanatory, so it is not (a), (b) or (c).", "repaired in round 1 as the fold payment, no card needed: the AGENTS.md ADR-0087 marker block listed 4 of the gate's 7 disposition categories.", "noted, not filed: scripts/pm/check-governed-queue-guard.mjs has no --test PATHS mode (round-1 finding, unchanged)." ] }Generated by Claude Code
hotlong commentedon Sep 8, 2026
ACCEPT — flight B, PR #16743 at head
1c5673488after one patch round (skills seat, hotlong, sessionsession_01P58euzUXCVJNwmhuPC9DXY, contract-tier review in seat, 2026-09-08T03:52Z; reports 5578512590 and 5578745311 read; the diff, the ruling 5564758585 and the check runs read on GitHub rather than the reports' narrative).Checklist: draft ✓, base
main✓, first lineFixes #16149✓; changed files 1 =AGENTS.md, the claim's declared surface (the merge commit brings onlyorigin/main's own change) ✓;skip-changeset✓ (nothing publishes AGENTS.md); ratchet 1068 → 1067 — a cap, so the net decrease is legal — and the per-line 120-byte budget met after the dev's reflow ✓; fold payment verified by the seat onorigin/main7c12e475: all seven ADR-0087 disposition categories live inscripts/check-adr-0087-registration.mjs's FIXIT output, and nothing underscripts/asserts AGENTS.md carries the marker block (control: 5adr-0087mentions remain in AGENTS.md) — the cut copy listed 4 of 7 and was a misleading duplicate, not a rule ✓; the paragraph carries the ruling's two structural costs, the trunk-branch route with both recorded workarounds, and the no-gate/no-policy boundary ✓; item 3 removed in the patch round — the ruling grades it "a defect independent of stacking", split out to #16482, so writing it as an inherent cost would go false when that card lands ✓; 14/14 derived gates exit 0 at1c5673488,--ranreconciled, governed predicate exit 3 ✓.Declared deviation from the ruling's letter, accepted: "pointing at this card" is mechanically unavailable in AGENTS.md (
check-skill-id-lint's EXTRA_FILES, pattern/#[0-9]{3,}/), so the pointer lives in the PR body (Fixes #16149) and the paragraph is self-contained — that gate's own prescription. Seat erratum on record: the dispatch namedcheck-governed-queue-guard.mjs --testwhere the predicate ischeck-governed-merges.mjs --test; the dev ran the right one. The dev's body-edit reading (anissue_writebody update on a PR appended no footer; attribution rides the commit trailers) is carried to the readings flight as a candidate, not written here.CI on
1c5673488at 03:44Z: Lint & Repo Gates and Type Check · workspace in progress, the rest green or skipped by filter. Terminal: governed (AGENTS.md) ⇒ the PR stays draft;needs-user-decision+ the seat's 速读终稿 go on the PR; review requested from os-zhuang, PR assigned to hotlong (author-identity fallback). #16633 (same file) is dispatched once this is onmain. This card stayspm:dispatchedwith its assignee until the merge closes it.Generated by Claude Code
hotlong commentedon Sep 8, 2026
Landing record — skills seat (hotlong, session
session_01P58euzUXCVJNwmhuPC9DXY), 2026-09-08T04:28Z: PR #16743 MERGED through the merge queue at 2026-09-08T04:26Z under os-zhuang's APPROVED review (5137116866 on head1c5673488; the seat armed auto-merge 03:58Z after its own revert error, recorded on the PR). ACCEPT 5578838078.pm:dispatchedand the assignee are cleared here in one write; labels left:enhancement·tooling·domain:skills·priority:p3. Read back after the write. The same-file follow-up #16633 (the PR-body footer sentence) is released by this landing and is claimed next.Generated by Claude Code