Skip to content

Commit 100303c

Browse files
pm-dispatch: an open PR names its owner — pr_create assigns the claim's Account, a hand-over re-assigns it, and H76 reports an unowned PR (#30796)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} --> _Requested by **Elon** · [project thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DMkvesLnTm6vYxaHQzFtixa)_ domain:skills#1 · os-elon-musk · session_016WV4d1MNyKiUFDBccFX8Cc Fixes #29828 Clause-②: no Metadata-protocol: none ## 维护者速读 - **改了什么**:按裁决 A 落地「PR 挂处理人」。开发经中继 `pr_create` 开 PR 时就把处理人挂成认领评论里的 `Account:`(即卡的处理人);换手(兄弟席接管、释放、改派)与认领变更同笔改 PR 处理人;交棒请审时仍 ⛔ 不请席位自己的账号。半状态巡查新增 H76 行:开着的、非信箱 PR 没有处理人就列出来(只报告,不是门禁)。 - **为什么改**:原规则禁止 PR 挂处理人,实测今天开着的 52 个 PR 里 0 个有处理人,GitHub 列表上看不出谁负责,排查闲置 PR 只能逐个读评论。 - **风险与回滚**:只动 `.claude/**` 规则文本(Tier S)与 `scripts/pm/` 巡查工具,不发布(`skip-changeset`)。中继本来就支持 `pr_create` 带 `assignees`,不改代码。H76 不写任何标签、处理人或评论,不挡合并。各规则文件行数不变、每行仍在 120 字节内,未抬任何上限。回滚即 revert。 - **先看**:① `.claude/skills/pm-dispatch/references/execution-duties.md` 认领节第 69 行(规则本体与换手同笔);② `scripts/pm/check-half-states.mjs` 的 `h76OpenPrWithoutAssignee` 与 sweep 里的接线;③ `.claude/skills/pm-dispatch/SKILL.md` 第 198–199 行(交棒请审只留「不请席位自身账号」)。 - **两分钟验证**:`node scripts/pm/check-half-states.mjs --self-test`,末行电池清单里应见 `H76 unowned open PR 12/11`,并以 0 退出。 - **需要你做的**:无,席位落地(Tier S,席位达档复核 PASS 且全绿后落地;存量 PR 的一次性补挂由席位在规则落地后经中继执行)。 ## What changes Ruling record 6674390671 (letter A, maintainer 「按推荐裁」) on #29828, encoded in the three texts it names plus every restatement found under `.claude/**`: - `.claude/agents/os-dev.md` rule 2 (L38): the PR's assignee is the claim's `Account:`, carried by `pr_create`; a hand-over is the seat's. Was 「PR ⛔ 不带 `assignees`(中继虽收),席位交棒才派」. - `.claude/agents/os-dev.md` write budget (L62): `pr_create` carries labels and assignees. Was 「⛔ 无 assignees」. - `.claude/skills/pm-dispatch/references/execution-duties.md` 认领 (L69; L67 at `1371b9d8`): the PR is assigned to the claim's account and a hand-over re-assigns it in the same stroke. Was 「PR ⛔ 不派席位账号」. - `.claude/skills/pm-dispatch/SKILL.md` hand-off step ③ (L198-199): 「⛔ 永不派/请席位自身账号」 keeps only the request half (the ruling replaces the assign half alone; a review request to the seat's own account stays forbidden); 「`pr_create` 不请不派」 becomes 「`pr_create` 派不请」. - `.claude/skills/pm-dispatch/references/dispatch-runbook.md` (L140): a card thread does not write the CARD's assignee — the PR's is now written by its `pr_create`. - `scripts/pm/check-half-states.mjs`: row **H76**, report-only, band `state` (H1's): an open PR with no assignee, a `pm:mailbox` PR excepted. The mailbox label is `mailbox-open.mjs`'s `MAILBOX_LABEL`, imported lazily as H72 does; when it cannot be loaded every unowned PR fires UNJUDGED, never clean. Drafts are included. Free: it reads the open listing the sweep already holds. ⛔ No gate wiring. Every file keeps its line count (each edit rewrites its own line in place) and every touched line stays within the 120-byte line budget; no ceiling moved. ## Tests - `node scripts/pm/check-half-states.mjs --self-test`: new battery `H76 unowned open PR` (12 cases, pin 11): the firing, a ready PR firing like a draft, the assignee exemption (list field and legacy single field), the mailbox exemption beside its unlabelled twin, closed and missing rows, the unread-label UNJUDGED leg for null / undefined / empty, an assigned PR staying clean with the label unread, not-loud, band + emitted, the lazy-import wiring, the roster floor. - Live probe (read-only, offline predicate over a REST listing, 2026-11-06 ~03:05Z): 52 open PRs, 0 assigned, 13 unassigned `pm:mailbox` PRs exempt, 39 would fire H76. ## Acceptance notes - The relay needs no change: `scripts/pm/fleet-write/validate.mjs` accepts `assignees` on `pr_create` (its own self-test pins the shape) and `ops.mjs` sends it as the second leg. Two relay COMMENTS still restate the old rule — the `ops.mjs` header (L103-105, "a dev's `pr_create` carries no `assignees` at all") and the `pr_create` row comment (L2093-2094). They are outside this card's surface while PR #30782 edits `ops.mjs`; carrier: the seat's relay-docs follow-up card. - `AGENTS.md` L403-404 restates the old rule ("nor the PR's: `pr_create` carries none; the seat sets it at hand-over"). `AGENTS.md` is Tier H and outside this card's surface; carrier: the seat files it. - The relay's governed-review plan (`execute.mjs`, `pr_ready`) and H43 count an ASSIGNED approver as covered. A claim's `Account:` is never a `GOVERNED_APPROVERS` account by rule (SKILL.md: an approval account never sits a seat), so the new assignee cannot mask a review request; noted because one open card (#30292) carries an approver account as assignee — its PR is not on a governed path today. - H76 reads no "unassigned with a note" exemption: a bot PR the seat leaves unassigned keeps reporting each sweep (report-only). Assigning the owning lane seat's account, the ruling's first arm, silences it. - The one-time backfill is NOT run here: the per-PR list (PR → card → assignee to set) is in the report comment on #29828, for the seat to run through the relay after this lands. - Numbered H76 because H75 is PR #30778's. ## Verification Local subset, recorded as `COMMAND :: exit CODE` and reconciled with `node scripts/pm/dispatch-gates.mjs --ran FILE --repo objectstack-ai/objectstack`: - At `7c76c755` (this change before the `origin/main` merge): all **58** derived families exit 0, reconciliation 58 derived / 58 run / 0 NOT-MEASURED; `pnpm lint` exit 0. That run includes `check:pm-half-states`, `check:pm-skill-ratchet`, `check:pm-skill-id-lint`, `check:pm-governed-prose`, `check:skill-frame-sync`, `check:doc-authoring` and `check:pm-dispatch-gates`. - The head carries one more commit, a plain merge of `origin/main` (bringing in PR #30778, which also edits `os-dev.md`, `SKILL.md` and `check-half-states.mjs`); the branch's delta against `main` is byte-identical (5 files, +92 / -6). The same 58 families are re-run on that head; their record is in the os-dev report on #29828. - CI families (Lint & Repo Gates, Test Core and the rest) are read from this PR's check-runs, not re-run locally. ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. (No schema touched.) - [x] 2. Every name I added uses the casing for its kind. - [x] 3. No formatter ran; `pnpm lint` passes. - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. - [x] 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. (Publishes nothing: `skip-changeset`.) - [x] 6. `packages/spec` touched: its generated artifacts are regenerated and committed. (Not touched.) - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English. - [x] The *Before Submitting* list in CONTRIBUTING.md is done. --- _Generated by [Claude Code](https://claude.ai/code/session_016WV4d1MNyKiUFDBccFX8Cc)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7c164cf commit 100303c

5 files changed

Lines changed: 92 additions & 6 deletions

File tree

‎.claude/agents/os-dev.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ model: opus
3535
- 同批 agents 共用一个 scratchpad 目录,自然命名的文件会被彼此静默覆盖。
3636
2. **卡 assignee 归 PM。** 派发原子对已把它设好;共享身份下该字段答不了是谁。
3737
- 你的身份位是认领评论里的分支;仓 CLAUDE.md 的 claim-first 已由 PM 的认领满足。
38-
- 恒不写卡的 assignee(空也开工,报 `summary`);PR ⛔ 不带 `assignees`(中继虽收),席位交棒才派。
38+
- 恒不写卡的 assignee(空也开工,报 `summary`);PR 派认领 `Account:`(`pr_create` 带),交棒归席位。
3939
- 发现与他人在途工作重复,停下报 `blocked`。
4040
- PR 上不是你设置的状态属于另一个 actor:⛔ 永不去纠正;疑问进报告,挡住报 blocked。
4141
- 回退他人的操作(尤其 ready 翻转)永不轮到你;把意外写进 `summary`。
@@ -60,7 +60,7 @@ model: opus
6060
- 写工具自读所需变量;⛔ 永不打印环境变量的值,转录是 AGENTS.md 禁落令牌的日志行。
6161
- 拼法不限于 `env`、`printenv`、`set`、`export -p`、`echo $VAR`、`cat /proc/*/environ`。
6262
- 判存在只用不印值形式 `[ -n "${X+x}" ] && echo set`;已印出 ⇒ `deviations` 只点名变量名。
63-
- 写预算三笔:`git push`、`pr_create`(draft,含 labels、⛔ 无 assignees)、`os-dev-report` 评论。
63+
- 写预算三笔:`git push`、`pr_create`(draft,含 labels 与 assignees)、`os-dev-report` 评论。
6464
- 卡与线程只走 payload 档(公开仓单卡网页内嵌 JSON,拼写住 platform-readings)或单卡 REST 读。
6565
- 三类发现进报告交席位代立,不 `POST /issues`、⛔ 不静默弃报;PM 去重读数当既有事实用。
6666
- PR 正文 dev 只写一次,在开 PR 那一笔,⛔ 不 `PATCH`;事后要改的报告点名改法,席位代写。

‎.claude/skills/pm-dispatch/SKILL.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
195195
- 批准判定单源 = 队列守卫常量 `GOVERNED_APPROVERS`:授权账户 APPROVED 即算,⛔ 不卡 `commit_id`。
196196
- 批准后再推亦不过期;席位落地 = 过落地前检、清标、ready、auto-merge,踢出/变基同法。
197197
- ③ 请审 = 席位交棒:ACCEPT 与现 head 同形 PASS 俱在案,同轮中继 `pr_request_reviewers` 请审批人。
198-
- 作者是审批人 ⇒ `assign` 它、请其余(请它必 422);⛔ 永不派/请席位自身账号;Tier S 不交人。
199-
- `pr_create` 不请不派;`pr_ready` 只补交棒漏;非例外 head 移 ⇒ 撤挂回等;脱中继 PR 自读请/派。
198+
- 作者是审批人 ⇒ `assign` 它、请其余(请它必 422);⛔ 永不请席位自身账号;Tier S 不交人。
199+
- `pr_create` 派不请;`pr_ready` 只补交棒漏;非例外 head 移 ⇒ 撤挂回等;脱中继 PR 自读请/派。
200200
- 速读「需要你做的」求批点名 PASS 评论 id+`Head-sha`;无 PASS ⇒ 写 contract review owed 不求批。
201201
- ④ 轮报单列 awaiting a human merge 并现读请审人;⛔ 未请审不在 chat 报「等你批」,先补请。
202202
- skills 车道自有 PR:纯代码面如 `scripts/pm/` 由本席按达档自审(清单不减)后落地。

‎.claude/skills/pm-dispatch/references/dispatch-runbook.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
- 席位留认领文本/派发令/契约复核/ACCEPT/落地;线程实施、开 draft PR、驱动 CI 与可合并。
138138
- 线程 ⛔ 不做 harness 开 PR 后指派/请审:「审核通过才会推送给我审核」,请审是席位交棒。
139139
- 派发令由 coordinator 写进线程开场消息,`Writes:` 行逐字在内,⛔ 不落共享目录;卡上留指针。
140-
- coordinator 开线程即读线程分支交席位(读不到则线程自报);⛔ 线程不认领、不写 assignee。
140+
- coordinator 开线程即读线程分支交席位(读不到则线程自报);⛔ 线程不认领、不写卡 assignee。
141141
- 席位写 assignee+`pm:dispatched`+带该 `Branch:` 的认领;线程核对最新认领指向本分支方开工。
142142
- 分支约定仍是 `claude/issue-<n>-<slug>`;线程只能推指定分支是实测平台例外,认领如实写。
143143
- worktree 照建;仓 `.claude/agents` 类型未加载(实测),线程照读 `os-dev.md`。

‎.claude/skills/pm-dispatch/references/execution-duties.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
## 认领(先认领后动工)
6767

6868
- 归属 = session ID,⛔ 不认作者字段;`Account:` 派生自 assignee,不等即半态、持卡席下笔补正。
69-
- 卡 assignee 归 PM,dev 恒不写;PR ⛔ 不派席位账号;在飞 PR 读 `head:claude/` 开 PR 正文点名的卡。
69+
- 卡 assignee 归 PM,dev 恒不写;PR 派认领账号,交棒同笔改;在飞 PR = `head:claude/` 正文点名本卡。
7070
- 部分落地(PR 带 `Refs #N (item k)`,⛔ 不 `Fixes`)即释放:合入同笔回 `pm:queue` + 清 assignee。
7171
- `Release:` 行点名已落与余项;余项整落 `ui/**` 外他席树 ⇒ 点名其改标,拆分加 `pm:retriage`。
7272
- 派发前按序执行原子对:① Assign @me,并把 `pm:dispatched` 与摘 `pm:queue` 放进同一次标签写入。

‎scripts/pm/check-half-states.mjs‎

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15720,6 +15720,48 @@ export function h72OffTableMailboxLines(reading, nowMs = Date.now()) {
1572015720
);
1572115721
}
1572215722

15723+
// ---------------------------------------------------------------------------
15724+
// H76 — an OPEN PR with NO assignee, a `pm:mailbox` PR excepted. Ruling record
15725+
// 6674390671 (letter A): a PR names its owner — the dev's `pr_create` carries
15726+
// the claim's `Account:` as its assignee, and a hand-over (sibling takeover,
15727+
// release, reassignment) re-assigns the PR in the same stroke as the claim
15728+
// change (`references/execution-duties.md` 认领). The same ruling makes this
15729+
// row report-only, ⛔ no gate. A mailbox is a seat's doorbell, never a delivery
15730+
// (`project-forms.md` 〈信箱 PR〉), so it is exempt; its label is
15731+
// `mailbox-open.mjs`'s MAILBOX_LABEL, handed in by the sweep, never spelled
15732+
// here. When the sweep could not load that label the row cannot tell a mailbox
15733+
// from a delivery, so it fires UNJUDGED, never clean (#4690). Drafts are
15734+
// INCLUDED: a dev's PR stays a draft until its seat lands it. Free — it reads
15735+
// the open listing already in hand.
15736+
// ---------------------------------------------------------------------------
15737+
15738+
/**
15739+
* H76 — null when clean or out of scope, else the finding sentence.
15740+
*
15741+
* @param {object} pr — a `/pulls?state=open` list row.
15742+
* @param {string} mailboxLabel — `mailbox-open.mjs`'s MAILBOX_LABEL, handed in by the sweep; anything else is unread.
15743+
*/
15744+
export function h76OpenPrWithoutAssignee(pr, mailboxLabel) {
15745+
if (!pr || pr.state === 'closed') return null;
15746+
if ((pr.assignees ?? []).length > 0 || pr.assignee) return null;
15747+
if (typeof mailboxLabel !== 'string' || mailboxLabel === '') {
15748+
return (
15749+
`${UNJUDGED_MARKER} open PR with NO assignee, and the mailbox label could not be read this sweep — ` +
15750+
'whether it is an exempt mailbox PR is UNJUDGED, not settled. Read its labels by hand: a mailbox is ' +
15751+
'exempt, any other open PR owes its owner as assignee.'
15752+
);
15753+
}
15754+
if (labelNames(pr).includes(mailboxLabel)) return null;
15755+
return (
15756+
'open PR with NO assignee. A PR names its owner (ruling record 6674390671): the dev\'s `pr_create` carries ' +
15757+
'the claim\'s `Account:`, and a hand-over (sibling takeover, release, reassignment) re-assigns the PR in the ' +
15758+
'same stroke as the claim change. Remedy — WHO and HOW: the seat holding the card this PR names assigns that ' +
15759+
'card\'s assignee through the relay (`assign` op, the PR number as `issue`); a bot PR with no card takes its ' +
15760+
'owning lane seat\'s account, or stays unassigned with a note. ⛔ Report-only: nothing is written from this ' +
15761+
`script. Out of scope: a \`${mailboxLabel}\` PR (a seat's doorbell, never a delivery).`
15762+
);
15763+
}
15764+
1572315765
// ---------------------------------------------------------------------------
1572415766
// H64 (#18069, re-keyed by #18237) — a seat- or dev-signed artefact that names
1572515767
// no session.
@@ -19910,6 +19952,11 @@ export const HALF_STATE_FAMILY_BAND = Object.freeze({
1991019952
// is stopped (not `stall`), and no write on the board repairs a sent comment
1991119953
// (not `state`) — the repair is the next bell, spelled from the table.
1991219954
H72: 'inventory',
19955+
19956+
// H76 is a `state`, H1's band for H1's reason: a live PR half-written — the
19957+
// owner the ruling makes it name is missing, and the repair is one relay
19958+
// `assign` on the board. ⛔ Not `stall`: an unowned PR can still land.
19959+
H76: 'state',
1991319960
});
1991419961

1991519962
const FAMILY_BAND_RANK = new Map(HALF_STATE_FAMILY_BANDS.map((b) => [b.name, b.rank]));
@@ -23797,6 +23844,22 @@ async function sweepInto(findings, seen, seenPrs, seenMerged, seenUnscoped, seen
2379723844
}
2379823845
}
2379923846

23847+
// H76 — an open PR with no assignee, off the listing above, free. The mailbox
23848+
// label is imported LAZILY for H72's reason (banner above `h72NeedsThread`);
23849+
// a failed import leaves it unread, and every unowned PR then fires UNJUDGED.
23850+
{
23851+
let mailboxLabel = null;
23852+
try {
23853+
({ MAILBOX_LABEL: mailboxLabel } = await import('./mailbox-open.mjs'));
23854+
} catch {
23855+
mailboxLabel = null;
23856+
}
23857+
for (const pr of seenPrs.values()) {
23858+
const unowned = h76OpenPrWithoutAssignee(pr, mailboxLabel);
23859+
if (unowned) findings.push([pr, 'H76', unowned]);
23860+
}
23861+
}
23862+
2380023863
// H16 — the only predicate here whose input no listing carries:
2380123864
// `mergeable_state` lives on the single-PR endpoint alone. One GET per
2380223865
// CANDIDATE (the gathering policy is `h16NeedsDetail`, which answers from
@@ -25309,6 +25372,9 @@ export const SELF_TEST_BATTERIES = Object.freeze({
2530925372
// through this predicate — lives in record-recognisers.mjs's doorbell battery,
2531025373
// because this self-test cannot import that module (H62's banner).
2531125374
'H72 mailbox off-table bells': 20,
25375+
// Registered with the unowned-PR row, pin just under the count: the firing, the assignee/mailbox/closed
25376+
// exemptions, the unread-label UNJUDGED leg, the text, the band and the wiring.
25377+
'H76 unowned open PR': 11,
2531225378
// Registered with the ruled-card-in-the-box row (#29386), pin just under the
2531325379
// count: the firing case, the label / fence / anchoring / id controls each
2531425380
// beside its positive twin, the threshold boundary, the governing stamp, the
@@ -28656,6 +28722,26 @@ async function selfTest() {
2865628722
b(BATTERY28675, '⭐ H72: the sweep takes the ONE reader and the opener\'s label LAZILY — `mailboxEvents` from record-recognisers.mjs, MAILBOX_LABEL from mailbox-open.mjs — and spells no doorbell key of its own', (() => { const src = readFileSync(fileURLToPath(import.meta.url), 'utf8'); return src.includes("import('./record-recognisers.mjs')") && src.includes("import('./mailbox-open.mjs')") && !/^import [^\n]*from '\.\/(?:record-recognisers|mailbox-open)\.mjs'/mu.test(src) && !src.includes(['MAILBOX_KEYS', '='].join(' ')); })(), true);
2865728723
b(BATTERY28675, 'floor: this battery is DECLARED on the roster, with a positive pin', Object.prototype.hasOwnProperty.call(SELF_TEST_BATTERIES, BATTERY28675) && SELF_TEST_BATTERIES[BATTERY28675] > 0, true);
2865828724

28725+
// -- H76: an open PR with no assignee (ruling record 6674390671, letter A). The fixture is a relay-opened dev
28726+
// draft as the card measured them (26 of 27 open PRs unassigned), offline, never a live read.
28727+
const BATTERY76 = 'H76 unowned open PR';
28728+
const MAILBOX76 = 'pm:mailbox';
28729+
const pr76 = (extra = {}) => ({ number: 30778, state: 'open', draft: true, assignees: [], assignee: null, labels: [{ name: 'skip-changeset' }], user: { login: 'objectstack-fleet[bot]', type: 'Bot' }, ...extra });
28730+
const row76 = String(h76OpenPrWithoutAssignee(pr76(), MAILBOX76) ?? '');
28731+
b(BATTERY76, 'H76 fires: an open dev draft with no assignee and no mailbox label', row76.length > 0 && !isUnjudgedFinding(row76), true);
28732+
b(BATTERY76, 'H76 row: names the ruling, the claim\'s `Account:`, the relay `assign` op, the bot-PR arm and the report-only boundary', ['ruling record 6674390671', 'the claim\'s `Account:`', '`assign` op', 'owning lane seat\'s account', 'Report-only'].every((x) => row76.includes(x)), true);
28733+
b(BATTERY76, 'H76: a ready (non-draft) PR fires exactly like a draft — drafts are included, not the only population', typeof h76OpenPrWithoutAssignee(pr76({ draft: false }), MAILBOX76), 'string');
28734+
b(BATTERY76, '⛔ H76: a PR with an assignee is clean — the list field or the legacy single field', [h76OpenPrWithoutAssignee(pr76({ assignees: [{ login: 'os-elon-musk' }] }), MAILBOX76), h76OpenPrWithoutAssignee(pr76({ assignee: { login: 'os-elon-musk' } }), MAILBOX76)].join(), ',');
28735+
b(BATTERY76, '⛔ H76: an unassigned `pm:mailbox` PR is exempt, and its unlabelled twin is not', [h76OpenPrWithoutAssignee(pr76({ labels: [{ name: MAILBOX76 }, { name: 'pinned' }] }), MAILBOX76), typeof h76OpenPrWithoutAssignee(pr76({ labels: [{ name: 'pinned' }] }), MAILBOX76)].join(), ',string');
28736+
b(BATTERY76, '⛔ H76: a closed PR and a missing row are silent, never a crash', [h76OpenPrWithoutAssignee(pr76({ state: 'closed' }), MAILBOX76), h76OpenPrWithoutAssignee(undefined, MAILBOX76), h76OpenPrWithoutAssignee(null, MAILBOX76)].join(), ',,');
28737+
const unread76 = [null, undefined, ''].map((label) => String(h76OpenPrWithoutAssignee(pr76(), label) ?? ''));
28738+
b(BATTERY76, 'H76: an UNREAD mailbox label fires UNJUDGED, never clean — null, undefined and empty alike', unread76.every((t) => t.startsWith(UNJUDGED_MARKER) && isUnjudgedFinding(t)), true);
28739+
b(BATTERY76, '⛔ H76: …but an ASSIGNED PR stays clean with the label unread — the label is only the mailbox exemption', h76OpenPrWithoutAssignee(pr76({ assignees: [{ login: 'os-elon-musk' }] }), null), null);
28740+
b(BATTERY76, 'H76: not a loud finding — it never escalates a sweep', [isLoudFinding(row76), isLoudFinding(unread76[0])].join(), 'false,false');
28741+
b(BATTERY76, 'H76 band: registered as `state` (H1\'s), and the sweep really pushes it', `${familyBand('H76')}/${familyRegistryCoverage().emitted.includes('H76')}`, 'state/true');
28742+
b(BATTERY76, 'H76 wiring: every listed open PR is judged with the label taken LAZILY from mailbox-open.mjs, never spelled in the sweep', (() => { const src = readFileSync(fileURLToPath(import.meta.url), 'utf8'); return src.includes("({ MAILBOX_LABEL: mailboxLabel } = await import('./mailbox-open.mjs'));") && src.includes('const unowned = h76OpenPrWithoutAssignee(pr, mailboxLabel);'); })(), true);
28743+
b(BATTERY76, 'floor: this battery is DECLARED on the frozen roster with a positive pin', Object.hasOwn(SELF_TEST_BATTERIES, BATTERY76) && SELF_TEST_BATTERIES[BATTERY76] > 0 && Object.isFrozen(SELF_TEST_BATTERIES), true);
28744+
2865928745
// -- H73 (#29386): a RULED decision card still sitting in the decision box.
2866028746
// Positive controls beside every negative one: the label, the fence, the
2866128747
// anchoring, the id, the threshold, the governing stamp, the re-entry line.

0 commit comments

Comments
 (0)