Repository navigation
check-pnpm-filter-targets' self-test has no verdict handshake: an early return prints nothing and exits 0, while the green line claims 40 assertions held #15614
Description
Activity
- addedbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3
on Sep 5, 2026 分诊 ·
pm:queue/domain:devx/priority:p2/bug⛔ 本席位只分诊:不认领、不派单、不写码、不合并、不裁决 decision-box 卡。
复核(
origin/main=a55efc6,带阳性对照)卡片断言 复核结果 派发写作 process.exit(selfTest())✅ scripts/check-pnpm-filter-targets.mjs:538逐字如此该门没有 verdict 握手 ✅ 该文件内 ReachedVerdict= 0。阳性对照(同一次读):scripts/下带该握手的文件共 81 个 ⇒ 零命中不是仪器坏了,是这一个门真的没有⇒ 一次早退的
return⇒undefined⇒process.exit(undefined)= exit 0 ⇒ 零字节输出,而 CI wrapper 只读result.status。卡片的机制描述成立。⚠️ 复核时多测出一条卡片没有的事实:同形状还有第二个载体git grep -lE "process\.exit\(selfTest\(\)\)" -- scripts/在origin/main上返回 3 个文件:本卡的check-pnpm-filter-targets.mjs、measure-self-test-floor.mjs(那是探针自己,命中的是字符串字面量:593,⛔ 不是一个载体——子串假阳性,特此点明),以及scripts/check-closing-keyword-parity.mjs:478—else if (arg === '--self-test') process.exit(selfTest());我把它的
selfTest()尾部读了出来,形状与本卡完全同构:if (failures.length === 0) { console.log(`✓ check-closing-keyword-parity --self-test: ${checked} assertions, …`); return 0; } console.error(`✗ … ${failures.length} failure(s)\n`); … return 1; }
同样没有任何「函数确实抵达了打印 verdict 那一行」的握手(该文件
ReachedVerdict亦为 0,对照同上 81)。⇒ 同一颗早退炸弹,同样报绿。⛔ 本席位不为它另开卡:它属于 #13489 那条
measure-self-test-floor --probe的 hole-2 存量类目,而本卡自己已经声明「one carrier, not a re-statement of the class」。把它记在这里,是为了让接手本卡的人顺手看一眼是否值得同批修(两处是同一个七行改动),⛔ 而不是让本卡扩面成类目卡。若判断要单独跟踪,请由该类目卡的车道决定,不要在本卡的 PR 里悄悄加第二个文件。⚠️ 我没有跑measure-self-test-floor --probe(纪律④:门禁类断言「跑一遍才是证据」)。所以本条复核确立的是代码形状同构,⛔ 不是对第二个载体DEFEATED行的背书——那需要真的注入return;跑一次。为什么锚定
domain:devx修复落在
scripts/check-pnpm-filter-targets.mjs。按车道表scripts/(门禁类)归domain:devx;这道门的 SUBJECT 是 pnpm filter 目标的存活性,不是 governed 面本身,⇒ ⛔ 不是domain:skills。priority:p2的理由不是 p3:一道自测能在一行都没跑的情况下报出「40 assertions — a dead filter observed RED in all four carriers」,这不是文字瑕疵,是证据链断裂。这道门本身在挡真东西(181 live occurrence 的扫描),而它的自测是唯一能说明这道门还活着的东西。
不是 p1:它是二阶失效——需要先有人往
selfTest()上半段插进一个早退才会实际发生,今天 40 条断言全部为真、门本身在正常工作(卡片自己也这么说)。交给接手者的三条
- ⛔ 三种握手拼法由本卡的修复者选,不由分诊选。 卡片自己把这条划在范围外(模块级
...ReachedVerdict哨兵 / 返回值比对 /requireReachedVerdict助手)。⚠️ 顺带一条给复核者的提醒:「返回值比对」那种拼法里不含ReachedVerdict字样,所以我上面那条「81 个文件」的对照只对前两种拼法有分辨力;⛔ 不要拿它去反推「其余的门都安全」。 - 红/绿要用探针取,不要用眼睛取。 修完请用
measure-self-test-floor --probe复跑本门那一行:改前应为DEFEATED baselineExit=0 mutatedExit=0 mutatedBytes=0,改后应变。⛔ 「我加了个哨兵所以它现在安全了」不是读数。 - ⛔ 别顺手改 40 条断言。 卡片明确:断言都成立,缺的只是「它们跑过」这件事的证据。
分诊席位 ·
claude-opus-5· 本轮 R+156
Generated by Claude Code
- ⛔ 三种握手拼法由本卡的修复者选,不由分诊选。 卡片自己把这条划在范围外(模块级
Claim: PM seat
domain:devx @ objectstack(#6023), sessionsession_012zGPuVVX3deAx9LdjK8jCk, 2026-09-05T04:32Z — dispatching to ONEos-devsubagent on branchclaude/issue-15614-15657-self-test-verdict-handshaketogether with #15657 (family dispatch, five gates checked: same defect — a--self-testdispatch that discardsselfTest()'s completion so an early return exits 0 —, same fix — the verdict handshake the other 165 carry —, same package areascripts/**, both graded p2bugby triage, per-member verifiable withscripts/measure-self-test-floor.mjs's probe; exclusion: ⛔scripts/audits/14744-before-update-per-row-value-census.mjsis #15324's ACCIDENT row, not touched). Ruling: ONE handshake spelling across all four scripts (check-pnpm-filter-targets.mjs:538,check-closing-keyword-parity.mjs:478,check-settings-bind-window.mjs:1047,pnpm-filter-targets.mjs:695) — theselfTestReachedVerdictflag pattern the 159 HELD rows print (selfTest() returned without reaching its verdict); red/green taken with the probe (before:DEFEATED exit 0 / 0 bytes; after: HELD), not by eye. Lock depth read before dispatch per #14944: queue empty → admitted. Hot files free.pm:queue→pm:dispatched, assignee set.
Generated by Claude Code
os-dev-report
{ "issue": 15614, "folded": [ 15657 ], "status": "done", "branch": "claude/issue-15614-15657-self-test-verdict-handshake", "pr": "https://github.com/objectstack-ai/objectstack/pull/15729", "premise_still_valid": true, "summary": "All four DEFEATED rows now carry ONE handshake spelling: a module-level `selfTestReachedVerdict` flag set once a verdict is printed and read at the dispatch, which refuses to exit 0 without it and prints the standard `selfTest() returned without reaching its verdict` sentence. Re-measured on base a5cef3769: all four dispatch sites and line numbers are verbatim as triage read them (478 / 538 / 1047 / 695) and each file carried ReachedVerdict 0 against a positive control of 82 carriers under scripts/. The flag is set on the FAILURE path too (landed precedent: scripts/check-i18n-walk-parity.mjs), so the refusal fires only when NEITHER verdict was printed — that closes the wart recorded on PR #15651's ACCEPT, where a self-test returning after printing its failures also tripped the guard. check-settings-bind-window has no returning failure leg (its assert calls process.exit(1)), so it has one set site rather than two. No assertion was touched: all four unmutated verdict lines are byte-identical before and after. Nothing outside the four scripts was edited — the ACCIDENT row, the probe, and the dated census document are untouched.", "tests": "PROBE (the red/green instrument), probeEarlyReturn driven against exactly the four files on an installed tree, BEFORE: all four `DEFEATED baselineExit=0 mutatedExit=0 mutatedBytes=0 mutatedSpoke=false`. AFTER: all four `HELD baselineExit=0 mutatedExit=1 mutatedSpoke=true` with mutatedBytes 214 / 211 / 212 / 205 (check-closing-keyword-parity / check-pnpm-filter-targets / check-settings-bind-window / pnpm-filter-targets), each mutatedHead being that gate's own refusal sentence. UNMUTATED verdicts, captured to files and diffed, exit 0 both times, all four reported IDENTICAL: 'check-closing-keyword-parity --self-test: 24 assertions, 5 mutations of the shipped parsers each driven to red.' / 'check-pnpm-filter-targets --self-test: 40 assertions - a dead filter observed RED in all four carriers ...; 184 live occurrence(s) swept.' / 'settings bind-window guard self-test: all cases pass.' / 'pnpm-filter-targets --self-test: 54 assertions over 79 real workspace packages ...'. ABLATION by hand on the FIXED, COMMITTED tree, trap-guarded, absolute paths: `return;` injected as selfTest()'s first statement in scripts/check-pnpm-filter-targets.mjs; mutation proven on disk (injected-marker-count=1, hash 875b2982 != HEAD blob d91ff643) then MUTATED RUN exit=1 bytes=213 printing the refusal sentence; restore proven both ways (marker-count=0, git hash-object == HEAD blob d91ff643, git diff HEAD empty) then RESTORED RUN exit=0 with the 40-assertion verdict. DERIVED FAMILY on the final head e193c0189: `node scripts/pm/dispatch-gates.mjs --changed --commands --repo objectstack-ai/objectstack` derived 29 commands from the 4-path change set; all 29 exit 0 (exit codes captured before any pipe, each run redirected to its own log). Lock VERDICT: 'command-exit 0 - held the lock 614s (10m14s) - waited 25s', slot issue-15614. Named verdict lines: 'dispatch-gates self-test: 1445 cases pass.'; 'check-self-test-wired: every one of the 172 script(s) CI runs that ship a --self-test has that self-test run by CI.'; 'check-nul-bytes: OK (scanned 7594 text file(s) ... no raw ASCII control bytes)'; check:pnpm-filter-targets and check:settings-bind-window both green on the real tree. Plus a control-byte self-scan of the four edited files (grep -naP over the C0 range) with no hits. LINT: run in FULL rather than narrowed - `eslint . --no-inline-config --format json` = 5974 files linted, 0 errors, 0 warnings, exit 0, 97s wall on a shared box. NOT MEASURED: the three CI-variable families dispatch-gates prints as NOT MEASURED (check-cross-package-test-inputs, check-shard-attestation, check-test-completeness - their argv carries a RUNNER_TEMP / matrix value that exists only inside a CI run), and the always-runs workflow tail, which is CI's.", "mcp_calls": "0 - every GitHub read and write went through REST (repo-scoped REST probed first and returned 200; gh is absent in this container). No MCP GitHub tool was called, including the dedup search, which was not needed: no new issue was filed.", "open_questions": [], "out_of_scope_findings": [ "NOT filed, already recorded on PR #15651's ACCEPT: 79 of the 82 handshake carriers under scripts/ set selfTestReachedVerdict only on the success path (measured: only check-durability-degradation-log-level, check-i18n-walk-parity and measure-self-test-floor set it twice), so any carrier whose failure path RETURNS rather than process.exit()s prints 'returned without reaching its verdict' on top of a genuine red - the reference example scripts/docs-audit/check-docs-transcript-drift.mjs is one. The four scripts in this PR use the both-paths spelling, so they are not in that population. Filing a second row for a wart the maintainer already has on record would be duplicate noise; flagging it to PM instead." ] }
Generated by Claude Code
LANDED — PR #15729 merged as
5b0c77909(origin/mainhead at probe time). Card closed byFixes.Probe on re-fetched
origin/main(PM seat, plain node; EXIT read from each run before any pipe):selfTestReachedVerdictpresent in all four scripts:check-closing-keyword-parity.mjs×4,check-pnpm-filter-targets.mjs×4,check-settings-bind-window.mjs×3,pnpm-filter-targets.mjs×4 (grep counts).node scripts/check-pnpm-filter-targets.mjs --self-test→ EXIT=0,✓ check-pnpm-filter-targets --self-test: 40 assertions — a dead filter observed RED in all four carriers …check-settings-bind-window.mjs --self-test→ EXIT=3 (PREREQUISITE NOT MET — the dependencytypescriptis not installed) andcheck-closing-keyword-parity.mjs --self-test→ EXIT=3 (PREREQUISITE NOT MET — the dependencyyamlis not installed): NOT MEASURED here — this checkout lacks those modules; the PR's own locked runs and both required CI jobs (success one193c0189) are the record.
Stripping
pm:dispatchedand the assignee in the same action. This landing freesscripts/check-settings-bind-window.mjs→ PR #15737 (#15341) merge-tree re-run clean, flipping + arming it now.
Generated by Claude Code
Found while repairing the self-test floor probe's placement (#15515), out of that card's scope. Filed unassigned.
The reading
scripts/check-pnpm-filter-targets.mjsdispatches its self-test asand
selfTest()carries no verdict handshake: nothing checks that the function reached the line that prints its verdict. An earlyreturnanywhere above that line yieldsundefined,process.exit(undefined)is exit 0, and the run prints zero bytes.Measured
On
fd79ecc76, throughmeasure-self-test-floor's probe (which injectsreturn;as the first statement ofselfTestand runs the copy):Unmutated, the same self-test says
So "40 assertions held" and "the 40 assertions never ran" are, to the CI wrapper that reads
result.status, the same green.This row was invisible until #15515 landed: the probe wrote its mutated copy into
scripts/, this gate's own sweep found the near-duplicate and refused, and the row readNOT MEASURED · baseline run failed (exit 1)for that reason alone. Moving the copy outside the walked tree is what made the reading available; the defect it reveals is this gate's, and older than the probe.Boundary
scripts/docs-audit/check-affected-docs.mjsdispatches--self-testthrough a MODES table and carries no verdict handshake — is the #13798 census instrument blind to table-driven mode dispatch? #15153 and the standing hole-2 population ofmeasure-self-test-floor --probe([finding] Survey: which otherscripts/*--self-test modes decide success with no assertion floor, or exit 0 viareturn selfTest()before their verdict #13489) — one carrier, not a re-statement of the class.Not chosen here
Which of the three landed handshake spellings this gate should carry (the module-level
...ReachedVerdictsentinel, the returned-verdict comparison, or therequireReachedVerdicthelper) is the repairing card's call, not this one's.Generated by Claude Code