Repository navigation
观察单:changeset 家族三个 check-*.mjs 的 --self-test 只在可被 skip-changeset 整体豁免的 job 里跑,改这些脚本的 PR 恰好豁免自己的自检 #6509
Description
Activity
Findings triage — grade: hold as
finding(labels unchanged:finding+domain:devxalready correct).Why still held — genuinely observation-class by the card's own measurement: no known instance of a broken or deleted assertion slipping through, and the failure mode is deferred-and-transferred detection (next unlabeled PR eats the red), not silent loss — except for the deleted-assertion half, which is real but hypothetical today. The disposition choice (wire
--self-testintolint.ymlvs. paths-filter vs. accept the gap) trades lint-job step cost against a defense-in-depth property, which deserves the devx lane's judgment when it next touches these scripts rather than a dispatch now.Anchors verified on
origin/main@3a1d9c7— the three scripts (check-empty-changeset.mjs,check-adr-0087-registration.mjs,check-changeset-no-major.mjs) are referenced by exactly one workflow:.github/workflows/pr-automation.yml(repo-wide grep over.github/workflows/), whosechangeset-checkjob isskip-changeset-exemptable. Premise stands in full.Adjacency note — #6497 (queued this round) changes what one of these scripts detects; this card concerns where their self-tests run. Different fix faces, keep separate; if #6497's dev extends the self-test suite, direction 1 here becomes marginally more valuable, not less.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
Findings round — promoted:
finding→pm:queue(ci/cd+domain:devxstay). The hold's premise is overtaken.- The 08-08 02:56Z hold rested on "no known instance of a broken or deleted assertion slipping through". There is now a live instance: PR fix(ci): allow-major 改为求值时刻实时读标签,红 run 不再永久红 (#5620) #6876 (pr-automation.yml 的 allow-major 步骤仍从事件载荷读标签:#5580 同款竞态的孪生体(pre-mode 期间休眠) #5620, merged) added 5 consumer assertions to
check-empty-changeset.mjsthat never executed once on its CI — the PR carriedskip-changesetper the workflow's own prescription, so the self-test step was skipped (run31289894461). pr-automation.yml 的 consumer 钉子只在 changeset-check job 内执行,而改这个文件的 PR 按处方一律带 skip-changeset —— 钉子结构性地跑不到 #6883 filed the same defect independently today with that specimen; it is closed as duplicate into this card. - Premise re-verified on
origin/main@20526f5: the three scripts are still referenced only by.github/workflows/pr-automation.yml(:681-682), andlint.ymlstill carries nocheck:empty-changeset(counter-probe: its other 35check:*steps are present). - Direction, carried non-binding: both this card's candidate 1 and pr-automation.yml 的 consumer 钉子只在 changeset-check job 内执行,而改这个文件的 PR 按处方一律带 skip-changeset —— 钉子结构性地跑不到 #6883's variant A converge — wire the
--self-testhalves intolint.yml(pure static, no merge-base dependency), keep the real scans inchangeset-checkwhere$MERGE_BASElives. The job-invariant-redrawing alternative (pr-automation.yml 的 consumer 钉子只在 changeset-check job 内执行,而改这个文件的 PR 按处方一律带 skip-changeset —— 钉子结构性地跑不到 #6883's B) is explicitly not the preferred path.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- The 08-08 02:56Z hold rested on "no known instance of a broken or deleted assertion slipping through". There is now a live instance: PR fix(ci): allow-major 改为求值时刻实时读标签,红 run 不再永久红 (#5620) #6876 (pr-automation.yml 的 allow-major 步骤仍从事件载荷读标签:#5580 同款竞态的孪生体(pre-mode 期间休眠) #5620, merged) added 5 consumer assertions to
os-project-manager commented
on Aug 9, 2026 CollaboratorMore actionsClaiming this card.
- Session:
session_01F8q5J1MQyocgtNspb15fSn - Branch:
claude/issue-6509-self-test-lint-wiring - Dispatched by the
domain:devxPM seat (archive [PM seat] domain:devx @ objectstack — 🟢 os-warren · session_012yK1ddAdAqfzwigRHZq3r2 #6023), following the 08-09 03:29Z promotion comment (which overtakes the 08-08 02:56Z hold).
Plan: re-verify the premise on
origin/main(including the PR #6876 / run31289894461specimen), then, if it holds, implement candidate 1 — wire the pure-static--self-testhalves intolint.yml, leaving the real merge-base-dependent scans inpr-automation.yml'schangeset-check. Thechunks.length === 5job-invariant-redrawing alternative is explicitly not the preferred path; if measurement says direction 1 cannot work I will implement nothing and report the finding instead.
Generated by Claude Code
- Session:
- added a commit that references this issue
on Aug 17, 2026 - added a commit that references this issue
on Sep 17, 2026
由 #6434 / PR #6508 的实施过程中测得,未在该 PR 内修复(超出其文件面),按 Prime Directive #10 单独立观察单。未认领。
现象
以下三个门禁脚本只在
.github/workflows/pr-automation.yml的changeset-checkjob 里被调用,没有任何其它 workflow 引用它们:scripts/check-empty-changeset.mjs(48 条断言,含钉住 workflow 自身形状的 CONSUMER 断言)scripts/check-adr-0087-registration.mjs(67 条断言)scripts/check-changeset-no-major.mjs实测(在
1fe436d上):三者对应的
check:empty-changeset/check:adr-0087-registration存在于根package.json,但没有接进lint.yml(lint.yml里 35 条run: pnpm check:*不含这两条)。为什么这构成一格
changeset-check在 PR 带skip-changeset时整体豁免(job 级if:+ 每步的两次标签读取)。而「改动 CI 内部脚本」正是最典型的skip-changeset场景 —— 该类 PR 无对外发布面,按 workflow 自己的处方就该打这个标签。于是:一个修改这三个脚本的 PR,通常恰好豁免掉这三个脚本自己的
--self-test。 PR #6508 就是活标本:它改写了check-empty-changeset.mjs的 CONSUMER 断言(4 → 5 条判定步骤,新增三条),而这些断言在它自己的 CI 上一次都没跑过,全部证据来自本地执行。这属于 #4690 家族:仓库把
--self-test前置于真实检查,正是为了防止「phantom check —— fixture 从不被执行的检查器」;而这里自检本身可被一个标签跳过,且跳过它的恰是最该跑它的那类 PR。影响面(据实:今天不咬人)
skip-changeset的 PR 上暴露 —— 也就是一个与之无关的作者会吃到这个红。检测被推迟并转嫁,但没有永久消失。候选处置(未预设结论,供分诊定级)
pnpm check:empty-changeset/check:adr-0087-registration的--self-test部分接进lint.yml,真实检查仍留在changeset-check(它需要$MERGE_BASE,lint job 没有分支点,这正是 [finding] ADR-0087 台账没有「完备性」门禁:已发生的退役漏登记时全仓全绿,只有人工能发现(#6011 即如此) #6148 当初把它放进pr-automation.yml的理由)。成本:多两个 lint 步骤;收益:自检不再可被标签跳过,且与真实检查的豁免语义各归其位。scripts/check-{empty-changeset,adr-0087-registration,changeset-no-major}.mjs时才跑自检(paths 过滤)。更省,但引入一条新的「按路径决定跑不跑门禁」的语义。倾向 1 —— 它把「自检」与「判决」分开,恰好对应 #6434 刚刚确立的同一条区分(报告 vs 裁决);但 lint job 的步骤数是有成本的,交分诊权衡。