Skip to content

pm-dispatch(contract-review): the lane reviews its own PRs, triage takes only an owed review nobody claims (drafts included); one Contract-review-claim line per head; an in-repo owed-review list - #27295

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-27062-contract-review-ownership
Oct 28, 2026

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #27062
Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:契约复审归属改成「车道审自己的,分诊只接没人在审的」:欠审的 PR(含 draft)在现 head 上没有复审记录、没有有效认领,且满足 (a) 有交接行或等复核标记、(b) 等满一轮分诊约 60 分钟、(c) 车道席收班或不在总表之一,分诊才接;起审前先贴一行 Contract-review-claim:;欠审清单从会话临时脚本改成仓内脚本 scripts/pm/check-owed-reviews.mjs。
  • 为什么改:维护者原话「应该车车道没有人审查的你才负责契约复审对吧」「如何避免重复审查」「所以你需要更新 skills吧」。之前分诊只认交接行、扫描又跳过 draft,两个 Tier H draft 带着交接行等了约五轮;同时没有任何东西能防两个复审者同时审同一个 head。
  • 风险与回滚:只动协议文本、两个 PM 脚本与一个 package.json 脚本串,不碰产品包、门禁判定、workflow、队列守卫;认领行只是协调,⛔ 没有门禁读它。回滚 = revert 本 PR。
  • 先看:① .claude/skills/pm-dispatch/references/contract-review.md 新增 6 行(L23–L28:触发条件、认领行形状、失效与车道优先)与 L60 改写;② scripts/pm/record-recognisers.mjs 的 readContractReviewClaim / contractReviewClaimLapse / contractReviewClaims(风险点:同 head 双认时谁持有);③ scripts/pm/check-owed-reviews.mjs 的 owedReviewRow(TAKE/WAIT/HELD/DONE 判定)。
  • 两分钟验证:node scripts/pm/check-owed-reviews.mjs,预期首行 check-owed-reviews — objectstack-ai/objectstack, …: N open PR(s) read (M draft); K owe a contract review — …,其后每个欠审 PR 一行,TAKE 在前,退出码 0。
  • 需要你做的:无,席位落地(Tier S:席位达档契约复核 PASS 后入队)。

What changes

The card's Wanted 1–6 as amended by the 12:23Z scope amendment (drafts are in; an in-repo owed-review list).

  • Item 1, the lane reviews its own — unchanged (contract-review.md L20 「谁跑 = 派发席」).

  • Items 2–3, the gap-only trigger and the claim line — references/contract-review.md 〈复核归属与资格〉, six new lines after the hand-off line: triage takes only an owed PR (draft or ready) with no record and no live claim on the current head, and one of (a) a hand-off line naming the current head or the waiting label, taken the same round; (b) the head has waited one full triage round (about 60 minutes); (c) the lane seat has stood down or is absent from the roster. Every reviewer reads the PR first; a record or a live claim on the current head means do not start; otherwise it posts one claim line per head first:

    Contract-review-claim: SESSION · head FULL-SHA · UTC
    

    (the file spells the placeholders in angle brackets; they are spelled out here because the platform strips tag-shaped fragments). A claim lapses when the head moves or 2 hours after posting with no record; when a lane claim and a triage claim name one head the lane wins and triage replies once to withdraw and discards its subagent's work. Delta re-reviews stay with the earlier reviewer — the existing rule (now L41) 「只落发现的 commit 由同一复核者 delta 复核」 already says it for both sides, so no line was added for it.

  • 〈等复核标记〉 — L54 「只带标记无交接行者仍归本席,分诊 ⛔ 不碰…」 is deleted: the amendment makes the label condition (a), so that sentence is now false; its second half (a hand-off goes stale when the head moves) is carried by the new (a) line, which counts only a hand-off naming the current head. The ⛔ line (now L60) keeps check, workflow and queue guard off the label and adds the claim line to what they never read; 「巡查脚本」 leaves it because the owed-review list now reads the label as one owed limb (report-only, never a verdict).

  • Item 6, the round step — references/triage-duties.md L11–L12: each round runs check-owed-reviews.mjs first (open PRs including drafts, hand-off and claim lines read), and an owed review is claimed and taken the same round; L12 keeps the isolated at-tier subagent signed by the seat and the quota rule. The dropped clause 「交接行读法 record-recognisers.mjs」 has its home in the script, which reads hand-off lines through that file.

  • Item 5, the round record — references/triage-duties.md L16 in place: the review table row names the claimer (认领者 · 记录 head→现 head→状态).

  • Item 4, the recogniser — scripts/pm/record-recognisers.mjs, beside readContractReviewHandoff: CONTRACT_REVIEW_CLAIM_KEY / CONTRACT_REVIEW_CLAIM_TEMPLATE / CONTRACT_REVIEW_CLAIM_LAPSE_HOURS; readContractReviewClaim(body) (session in the signature line's session shape, imported; the FULL 40-hex head; the UTC minute, seconds allowed; read through stripSignatureLine); contractReviewClaimLapse (pure: live / head-moved / expired, timed from the comment's created_at); contractReviewClaims(rows, head, { now }) (the holder, lane first on a tie; a claim is triage's only when its comment is signed triage#N). ⛔ No gate reads it.

  • Item 6, the owed-review list — new scripts/pm/check-owed-reviews.mjs (named as scripts/pm/ names its report-only readers, check-half-states.mjs the model): read-only, prints one row per open PR (draft or ready) whose face owes a review — the face from reviewFace's path hits (reused, not re-implemented), the PR body's Clause-②: line through readClause2Line, and the waiting label; the record on the current head through locateReviewOfRecord (stale records name their reviewer, the delta owner); the hand-off through contractReviewHandoff; the claim through contractReviewClaims; the lane seat from the card's domain:* label against the open seat posts (fleet-roster.mjs parseSeat); a status TAKE / WAIT / HELD / DONE and the trigger that holds. Exit 0 on every read; a failed read prints sweep INCOMPLETE, never clean; usage errors exit 2. --self-test carries a battery roster, floor and verdict handshake.

  • Wiring (no workflow line) — root package.json check:pm-record-recognisers now runs record-recognisers.mjs --self-test && check-owed-reviews.mjs --self-test, so the existing lint.yml step runs the new self-test; check:self-test-wired is green on it.

  • Companion registration — the recogniser's claim battery pins the template and its 2-hour lapse verbatim in contract-review.md, a read of a governed file: the existing self-test-reads declaration (line 77, unmoved) names both files and GOVERNED_READ_FLOOR (scripts/pm/dispatch-gates.data.mjs) gains the row. dispatch-gates.self-test.mjs's census is unchanged (same declaration, same line).

Line budget

file before after ceiling
.claude/skills/pm-dispatch/references/contract-review.md 55 60 60
.claude/skills/pm-dispatch/references/triage-duties.md 102 102 102

Every edited line is ≤120 bytes (wc -c): contract-review.md L23–L28 116, 116, 105, 117, 64 (the code line), 120, L60 113; triage-duties.md L11 115, L12 118, L16 120. contract-review.md spends its 5 free lines plus the one freed by deleting L54 (home above). No re-wrap was used to buy a line.

Tests

Self-tests, counts before → after
  • node scripts/pm/record-recognisers.mjs --self-test: 276 → 297 cases (batteries 15 → 16; the claim battery 21 cases, floor 21).
  • node scripts/pm/check-owed-reviews.mjs --self-test: new, 49 cases in 8 batteries (floor 8), including a fixture modelled on the two Tier H drafts that waited (a workflow-step draft with a hand-off on its current head since 07:43Z; a narrowing draft whose first hand-off went stale on a merge-forward and was renewed): both list as TAKE under (a) hand-off, and read HELD once the triage claim is posted.
  • Ablations, each restored with blob == HEAD and an empty git diff HEAD (scripts/ablation-replace.mjs): the tie rule (holder = live[0]) reds 「the LANE wins a tie」 (1 of 297); the lapse boundary (>= → >) reds the lapse case (1 of 297); excluding drafts from the owed list reds the owed-review self-test (exit 1).
Live run, read-only (14:39Z)

node scripts/pm/check-owed-reviews.mjs exit 0 in 47 s: 22 open PRs read (16 draft); 16 owe a contract review — 3 to take, 8 waiting on the lane, 0 claimed, 5 reviewed on this head. The narrowing draft named on the card reads DONE (record on its current head, PASS, by the triage session; hand-off triage; claim lapsed); the workflow-step draft has since merged and is not listed.

Acceptance notes

  • The waiting label is hung by the dispatching seat at ACCEPT whenever a review is owed and no PASS is on file (〈等复核标记〉 L58). With the amendment it is condition (a), taken by triage the same round — so a lane seat that will review itself posts its claim line before or with the label; that is what keeps item 1 true. Noted, not changed: the label rule's text is outside this card's ruled scope.
  • dispatch-runbook.md 〈巡查常设项〉 still tells a cross-account reviewer to post a Claim:-shaped comment before a review; that is a second spelling of the review claim. Not touched here (that file is held by another claim this wave); noted for the seat.
  • The lint.yml step comment above check:pm-record-recognisers says it runs one file's self-test; it now runs two through the package script. A workflow comment is Tier H, so it is left as is.
  • Trigger (b) times the head from the later of its commit's committer date and the PR's opening; GitHub's API does not expose push time on the pull row, so a force-push of an old commit can read as waited longer than it has.
  • The verdict word (PASS / FAIL) is read by the list for display only, from the record's VERDICT: line; owed-ness never depends on it.

Verification

Local gates at dca7881 (derived by `dispatch-gates --commands`, reconciled with `--ran`)

node scripts/pm/dispatch-gates.mjs --ran ran.list --repo objectstack-ai/objectstack → exit 0: 「50 derived famil(ies) accounted for — 46 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3)」. Exit 0 on all 46 run, among them check:pm-skill-ratchet (contract-review.md 60/60, triage-duties.md 102/102, headroom 0), check:pm-skill-id-lint (104 files clean), check:pm-record-recognisers (297 + 49), check:pm-dispatch-gates (1935 cases, fast tier), check:pm-half-states (5034), check:pm-governed-merges, check:self-test-wired (244 scripts), check:ratchet-remedy-authority, check:entry-guard, check:parse-guard, check:nul-bytes; check:doc-formula-expressions after building its closure under the verify lock. Run by hand beyond the derivation: check:pm-governed-prose exit 0, check-governed-queue-guard.mjs --self-test exit 0 (401 cases). NOT MEASURED (exit 3, PREREQUISITE NOT MET — a full pnpm build; the diff touches only a script string in the root package.json): check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content — CI runs them.


Generated by Claude Code

@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 28, 2026
@github-actions github-actions Bot added size/l dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation labels Oct 28, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-justin · session_01QSeKYmhU5KEj1nukYhp1Tg

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: dca788103c73e096fb73db0a0ed3fbc110b73451
Local-runs: probe — the seat ran, in a detached read-only worktree of the head (no edit, no network): node scripts/pm/record-recognisers.mjs --self-test → ✓ 297 cases, node scripts/pm/check-owed-reviews.mjs --self-test → ✓ 49 cases / 8 batteries, check-skill-line-ratchet.mjs → ✓, check-skill-id-lint.mjs → ✓ 104 clean, check-governed-queue-guard.mjs --self-test → ✓ 401, check-half-states.mjs --self-test → ✓ 5034; the live read-only mode of the new script was NOT run by the seat (the dev ran it once: 22 open PRs read, 16 owe a review, exit 0)
Scope: .claude/skills/pm-dispatch/references/contract-review.md (L23–28 new, old L54 removed, L60 reworded), references/triage-duties.md (L11, L12, L16 in place), scripts/pm/record-recognisers.mjs (readContractReviewClaim, contractReviewClaimLapse, contractReviewClaims, the claim battery, the widened self-test-reads declaration), scripts/pm/check-owed-reviews.mjs (new, report-only), scripts/pm/dispatch-gates.data.mjs (GOVERNED_READ_FLOOR sixth row), package.json (check:pm-record-recognisers chains the new self-test) + card #27062's 「Wanted」 1–6 as amended (ruling 6460017532; amendment 6468887030 on the maintainer's words)

Read at 2026-10-28T15:05Z by the domain:skills#2 seat on the fetched head (merge-base 0d45c0e7): six files, +825/−11, 836 changed lines ≤ 3000 (check-governed-merges --pr 27295: two .claude paths, Tier S; package.json and scripts/pm/** off the register). The claim's tier was the default (no path mandate); this review is served at CONTRACT_REVIEW_TIER.

① Derived judgments

  • Items 2–3 (contract-review.md L23–28, each ≤120 B, the file now exactly at its ceiling 60/60): triage takes only an owed PR — draft or ready (the amendment) — whose current head has no record and no live claim, under one of (a) a hand-off naming the current head OR the waiting label, taken the same round; (b) the head has waited one full triage round (~60 min); (c) the lane seat has stood down or is absent from the roster; the owed list is node scripts/pm/check-owed-reviews.mjs, read-only. Before any review, lane or triage reads the PR: a record or a live claim on the current head ⇒ ⛔ do not start; else post the claim line first, one per head — Contract-review-claim: <session> · head <full sha> · <UTC> — lapsing when the head moves or 2 h after posting with no record; a tie on one head ⇒ the lane wins, triage replies once to withdraw and discards its output. That is the card's 2–3 verbatim in the file's register. The deleted L54 (「只带标记无交接行者仍归本席,分诊 ⛔ 不碰…」) was made false by the amendment (the label alone is now trigger (a)) — its surviving content (a hand-off must name the current head; a moved head needs a new one or the lane's own review) lives in (a) and in the lapse line. L60 drops 「巡查脚本」 from the no-reader list honestly (the owed-review script does read the label) and adds 认领行 to what no check, workflow or queue guard reads (item 4). Holds.
  • Item 6 (triage-duties L11/L12/L16, in place, 115/118/120 B, 102/102): each round first runs the owed-review script (open PRs including drafts, reading hand-off AND claim lines) and takes owed reviews in the same round after claiming; the isolated at-tier subagent and the never-downgrade rule kept; item 5: the round record names the claimer per head (认领者 · 记录 head→现 head→状态). The dropped clause (「交接行读法 record-recognisers.mjs」) lives in the script, which reads hand-offs through that module. Holds.
  • Item 4 (record-recognisers.mjs): readContractReviewClaim returns the hand-off reader's state shape (missing / unreadable / read {session, head, time, at}) — better than the order's {…} | null sketch because an unreadable claim must be reportable; contractReviewClaimLapse (head moved, or > 2 h with no record — the dev's ablation of >=→> and of the tie holder each turned exactly one case red) and contractReviewClaims(rows, headSha) (live claims, holder = the lane's when both exist). All read through stripSignatureLine like every reader since PR pm(post-stamped): every seat post opens with a signature line LANE#N · ACCOUNT · SESSION, refused without one; the recognisers skip it #27263; the battery (21 cases, floor 21) pins the template and the 2-hour lapse verbatim in contract-review.md, so text and reader cannot drift — the governed read is DECLARED (the self-test-reads line names both files; GOVERNED_READ_FLOOR gains its sixth row; the census needed no change: same line). Holds.
  • The owed-review script (check-owed-reviews.mjs, 602 lines, report-only): lists every open PR whose face owes a review with the record, hand-off, claim, lane seat and a TAKE / WAIT / HELD / DONE status and the trigger; it REUSES reviewFace, readClause2Line, locateReviewOfRecord, contractReviewHandoff and fleet-roster's parseSeat (no second implementation of the owed face); exits 0 on any completed or failed read (a failed read prints sweep INCOMPLETE), 2 only on a malformed command line, 1 only from --self-test — ⛔ not a gate. Its self-test models the two Tier H drafts the ui seat named (hand-off on the current head; hand-off renewed after a merge-forward): both TAKE under (a), HELD once a triage claim is posted. Wiring: no workflow line — the self-test runs inside the existing lint.yml step through package.json's check:pm-record-recognisers chain; check:self-test-wired green (244 scripts). Holds; the order's "exit 0 always" is correctly refined.

② Semver level

  • None owed: protocol text, PM scripts, a root package.json script string; no package touched. Clause-②: no, Metadata-protocol: none on the PR body match the claim; no Skills-docs: line owed; skip-changeset correct (dependencies is the labeler's reading of package.json, not a dependency change — the diff is one script string).

③ Boundary flags

  • Four derived families NOT MEASURED locally (check:dts-closure, check:dual-build-cjs-loads, check:lean-entry-closure, check:sourcemap-no-sources-content — prerequisite: a full build, triggered by the root package.json touch); the diff changes one script string, no package; CI's lanes carry them — read off the head's check-runs in the ACCEPT.
  • The lint.yml step comment still describes one self-test file — Tier H, left alone; the chain is in package.json. Noted.
  • Three Acceptance-note observations, agreed and carried: dispatch-runbook.md 〈巡查常设项〉 L44–45 still tells a cross-account reviewer to post a Claim:-shaped comment before reviewing — now a second spelling of the review claim (a later card; that file is held by another claim this wave); the 〈等复核标记〉 interaction (a lane seat that will review its own PR posts its claim with or before the label, else triage takes it the same round — this is the rule working, and the lane's own records are posted at ACCEPT anyway); trigger (b) times the head from the later of committer date and PR created_at (REST carries no push time — a force-pushed old commit can look older than it is).
  • Author objectstack-fleet[bot] through the relay; mcp_calls: 0; the report comment carries the signature; draft, no flip by anyone.

④ Design judgment

  • Against the maintainer's words (the lane reviews its own; triage only where nobody is reviewing; how to avoid duplicate reviews; "they had told you"): the gap is now defined by three mechanical triggers rather than one line, drafts are no longer invisible, the owed list is a script anyone runs rather than a session's memory, and two reviewers cannot start on one head because the first posts a claim that the second reads — with the lane winning any tie. Against the four-axis frame: focus (no gate, no workflow, one script chained into an existing step), AI-error (the claim template and lapse pinned in both text and reader; refusal to start, not tolerance), long-run (one owed-face function reused, one claim reader beside the hand-off reader). Holds. Residual: the second Claim: spelling in dispatch-runbook (noted above) and the roster-absence trigger (c), which depends on the roster being current.

Implemented-by: claude/issue-27062-contract-review-ownership
Reviewed-by: session_01QSeKYmhU5KEj1nukYhp1Tg

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:skills#2 · os-justin · session_01QSeKYmhU5KEj1nukYhp1Tg

维护者速读 — 席位终稿 · PR #27295 · head dca78810 · domain:skills#2 · 2026-10-28T15:19Z

  • 改了什么:把「谁复核这个 PR」从一句话变成可执行的三件:① 分诊只接「无人在复核」的 PR —— 现 head 无记录、无在生认领,且三触发之一成立(交接行点名现 head 或挂了等复核标记;head 等满一轮约 60 分钟;车道席已收班或不在名单),草稿 PR 也算(按你的话改的范围);② 复核前先贴一行认领 Contract-review-claim: <session> · head <sha> · <UTC>,一 head 一行,head 一动或 2 小时无记录即失效,撞车车道胜、分诊撤;③ 新脚本 scripts/pm/check-owed-reviews.mjs 只读列出所有欠复核的开 PR(含草稿)与 TAKE/WAIT/HELD/DONE 状态,分诊每轮开局先跑它。读法进 record-recognisers(自测 297 例,新增认领行 21 例),欠单脚本自测 49 例挂进现有 lint 链;无新门禁、无 workflow 改动。
  • 为什么改:你的原话「车道自己复核自己的,分诊只复核没人复核的」「怎么避免重复复核」「他们早告诉你了」—— 两张 Tier H 草稿等了数小时无人接,因为草稿不在分诊视野、「没人复核」只凭会话记忆判;本 PR 让空档由三个机械触发定义、欠单由脚本列、两席不可能同时起手。
  • 风险与回滚:协议文本两文件 + PM 只读脚本;脚本任何读失败都 exit 0(报 sweep INCOMPLETE),不是门;回滚 = revert 两个 commit。
  • 先看:contract-review.md L23–28(触发与认领行模板,60/60);triage-duties L11/L12/L16(102/102);record-recognisers.mjs 的 readContractReviewClaim / contractReviewClaimLapse / contractReviewClaims。
  • 两分钟验证:node scripts/pm/check-owed-reviews.mjs 列出当前欠复核的 PR;node scripts/pm/record-recognisers.mjs --self-test 297 绿;pnpm check:pm-skill-ratchet 两文件 headroom 0。
  • 需要你做的:无 —— Tier S(两条 .claude 路径;scripts/pm/** 与 package.json 不在受管名单),契约复核 PASS(6472602303)后席位按你今天的落地授权落地。
  • 席位意见:ACCEPT。六文件逐一读过;新脚本复用既有「欠复核面」函数而非第二套实现;认领模板与 2 小时失效在文本与读法两处同钉(自测消融各翻红一例);三条范围外观察实属后续卡,记 Acceptance notes。

席位核对 — ACCEPT · domain:skills#2 · session_01QSeKYmhU5KEj1nukYhp1Tg · 2026-10-28T15:19Z

  1. 形态:draft → main,首行 Fixes #27062,Clause-②: no、Metadata-protocol: none 行首在;六文件 +825/−11(836 行 ≤ 3000);assignee os-justin;skip-changeset 正确(dependencies 是 labeler 对 package.json 的读法,diff 只改一条脚本串,无依赖变动);两 commit;作者 objectstack-fleet[bot] 经中继,mcp_calls: 0;dev 报告首行带署名(6472536326)。
  2. 前提实测:席位在取回的 head(merge-base 0d45c0e7)上的 detached worktree 复跑 —— record-recognisers 自测 297 ✓、check-owed-reviews 自测 49 ✓、ratchet ✓(contract-review 60/60、triage-duties 102/102)、id-lint ✓、queue-guard 自测 401 ✓、half-states 自测 5034 ✓;新 .claude 行每行 ≤120 B;package.json 链 check:pm-record-recognisers 串入新自测;GOVERNED_READ_FLOOR 第六行在;check-governed-merges --pr 27295 ⇒ Tier S。范围按分诊改单 6468887030(草稿纳入)核对,与卡 Wanted 1–6 逐条对上(复核记录 6472602303 ①)。
  3. 门禁 check-runs(head dca78810,本笔读数 2026-10-28T15:19Z):47 check-runs,28 success · 19 skipped · 0 in progress · 0 failure;19 个 skip 由 check-expected-skips.mjs --check-runs-json(在 origin/main b4458075 的名单上)判定全部在册,exit 0;四族构建派生门(dts-closure / dual-build / lean-entry / sourcemap)席位未本地测,由 CI 的 Lint · Build Core 等 lane 承担,皆绿。
  4. 接受的偏差:① readContractReviewClaim 返回 missing/unreadable/read 三态而非令中的 {…}|null 草图(不可读的认领必须可报);② 脚本退出码细化为「读失败 exit 0 + sweep INCOMPLETE、用法错 exit 2、自测红 exit 1」,仍非门;③ 触发 (b) 的 head 时点取 committer date 与 PR created_at 的较晚者(REST 无推送时间);④ dev 推翻了我「reconcile-list 可复用」的假设,实测无此面;⑤ 脚本活读模式席位未亲跑(dev 跑过一次:22 开 PR,16 欠)。
  5. 范围外去向:none filed;Acceptance notes 三条留后续卡:dispatch-runbook 〈巡查常设项〉L44–45 仍叫跨账号复核者先贴 Claim: 形评论,成了复核认领的第二拼法(该文件本波另有认领在手,不并入);〈等复核标记〉与本认领行的互动(车道要自审则先于或同笔贴认领,否则分诊同轮可接 —— 即规则本意);lint.yml 步骤注释仍写单一自测文件(Tier H,不动,链在 package.json)。Skills-docs: 不欠(kind none)。
  6. 落地条款:Tier S;契约复核 PASS 评论 6472602303(head dca78810);全绿即席位经中继 pr_ready + automerge_enable 落地(本班维护者「你应该按照 pm-dispatch 技能审核并落地pr」在案);MERGED 后关卡摘 pm:dispatched;triage-duties.md 热文件队列放开 → pm-dispatch(triage): a lane seat may self-triage (p1/p2) a card that blocks its own in-flight work on clear evidence, then ask the triage seat to review #27061(本班不再派发,留队列无 assignee)。

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 28, 2026 15:21
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 28, 2026
Merged via the queue into main with commit a0aa8a1 Oct 28, 2026
48 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-27062-contract-review-ownership branch October 28, 2026 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/l skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants