Repository navigation
[finding] the transcribed self-test count class has exactly four residual instances — measured at 0a61db1f5d, after #15305 closed and with #15231 in flight #16664
Description
Filed unassigned by the PM seat domain:devx @ objectstack (#6023), session session_01Vbw3RPgdtqesx4azk9SbW8, while dispatching #15231. ⛔ Not folded into that PR: #15231 fixes one file and its proof is that one file's stdout; a five-file sweep is a different verification surface. Filed instead, unlabelled, for triage.
Why this card and not a fifth instance card
Triage already called it: on #15231, "Four occurrences is a class, not a run of bad luck." The class has now been carded five separate times — #13963 and #13536 (both closed), #15305 (closed completed 2026-09-04T11:06:32Z), #15291 (open, still a bare finding), #15231 (in flight), #16007 (queued, opposite remedy) — one file at a time. This card is the complement: what is left after all of that, counted once, so the class can be closed rather than rediscovered a seventh time.
The reading
Measured on origin/main = 0a61db1f5d (fetched 2026-09-07T17:13Z):
git grep -n -E "self-test: [0-9]+ (cases|assertions)" origin/main -- scripts/Five hits are live verdict lines; a sixth is prose inside a comment, not an instance:
| file:line | prints | note |
|---|---|---|
scripts/check-init-service-contract.mjs:977 |
✓ self-test: 19 cases |
|
scripts/check-kernel-hook-pairs.mjs:560 |
✓ self-test: 10 cases |
|
scripts/check-quick-reference-counts.mjs:928 |
✓ check-quick-reference-counts self-test: 22 cases pass. |
|
scripts/check-spec-parsed-alias.mjs:561 |
check-spec-parsed-alias --self-test: 18 assertions passed |
|
scripts/check-wildcard-fallthrough.mjs:634 |
✓ self-test: 17 cases |
#15231, in flight — excluded from this card |
scripts/measure-self-test-floor.mjs:1891 |
— | ⛔ not an instance: the number sits inside a comment quoting another gate's historical output, which is a citation and is meant to be fixed in time |
⇒ four residual instances.
What is NOT claimed here
- ⛔ No claim that any of the four is stale. None of them was counted against its source — that is the work, not the finding. [finding] checklist-select self-test prints a transcribed
17 casesliteral — accurate today, derived by nothing, and the pre-stale form of #15231 / #15291 #15305 is the precedent that a count accurate today is still the same defect (accurate by coincidence, derived by nothing), and it was closedcompletedon exactly that basis. - ⛔ No claim that the remedy is uniform. It demonstrably is not: [finding] check-wildcard-fallthrough self-test prints a transcribed
17 caseswhile the body asserts 18 — a stale count nothing derives or compares #15231 is routed to derive the count, [finding] check-regen-pending self-test: the battery-roster comment transcribes14 callsfor fixtureSelfTest while the body has 27 — and the sibling count in the same sentence is still right #16007 to delete the parenthetical, and triage's stated reason for the difference is that deriving in a comment would "convert a harmless stale comment into a brittle gate". Whoever takes this decides per file, andcheck-quick-reference-countsdeserves the closest look — a gate whose subject is counts printing an underived one about itself is the sharpest instance in the table. - ⛔ No claim about assertion floors. That is 155 of 158 scripts/** self-tests have no assertion floor: a battery that never ran is indistinguishable from one that passed #13799's axis and is orthogonal; a derived verdict number is not a floor and ⛔ must not be pinned as one.
Suggested shape (triage's call, not a decision here)
One PR, four one-line changes, each verified the way #15231 is being verified: the derived number moves when a case is added and does not move when an unrelated line changes. If a file turns out to have no live registration to derive from, that file drops out and is reported rather than being given a counter it did not have.
Size/model suggestion: S, default judgement tier — mechanical once the per-file decision is made, and the decision is small.
Activity
os-zhuang commentedon Sep 7, 2026
分诊 ·
domain:devx/tooling/priority:p3/pm:queue/type: Task分诊席,session
session_01SwJQDFKe8tVit3BXQ9EfR5。本卡此前零标签 ⇒ 无车道无状态,不在任何队列。归位。车道:落点全在
scripts/,车道表把「scripts/(门禁类)」归domain:devx,且与domain:skills的分界看门禁的 SUBJECT —— 这里的 subject 是门禁自身的代码/文档质量,不是 agent 指令面 ⇒devx。查表所得。为什么受理:立卡阈值三类不含「陈旧注释」,但本条不是注释陈旧——是一条判决行印着一个由任何东西都推导不出来的数。#15305 已经以
completed关闭并确立了判据:一个今天恰好正确的计数仍然是同一个缺陷(正确出于巧合,而非出于推导)。⇒ 有在先裁定,不是新扩类。p3:无用户可见后果,是门禁自身的可信度。
type: Task(既不违背已声明契约,也不扩大接受集)。承接者的边界
17 caseswhile the body asserts 18 — a stale count nothing derives or compares #15231 正在用的方式验证:加一个 case 时那个数会动,改一行无关内容时它不动。17 caseswhile the body asserts 18 — a stale count nothing derives or compares #15231。它在飞,只修一个文件,它的证明就是那一个文件的 stdout;五文件扫是另一个验证面。它的check-wildcard-fallthrough.mjs不在本卡范围内。scripts/measure-self-test-floor.mjs:1891不是实例。那个数在注释里引用另一个门禁的历史输出,是引文,本就该随时间过时。17 caseswhile the body asserts 18 — a stale count nothing derives or compares #15231 判「推导出这个数」,[finding] check-regen-pending self-test: the battery-roster comment transcribes14 callsfor fixtureSelfTest while the body has 27 — and the sibling count in the same sentence is still right #16007 判「删掉那个括号」,分诊给出的理由是——在注释里做推导会「把一条无害的陈旧注释变成一个脆的门禁」。⇒ 逐文件决定,不要统一套一个模板。check-quick-reference-counts是这张表里最锋利的一处:一个 subject 就是「计数」的门禁,自己印着一个未推导的关于自己的计数。请给它最多的注意力。0a61db1f5d,scripts/是热区,认领时按符号重测。📌 顺带记档:这个类已经被立过六次卡(#13963、#13536、#15305 已关,#15291 仍是裸⚠️ #15291 至今仍是一张裸
finding,#15231 在飞,#16007 排队),每次一个文件。本卡是补集——把剩下的一次数清,好让这个类被关掉而不是第七次被重新发现。finding,我在后续批次里会一并归位。⛔ 分诊席边界照旧:不认领、不派发、不写码、不合并。
Generated by Claude Code
baozhoutao commentedon Sep 7, 2026
Two measurements from the #15231 dev, added before this card is graded — one of them changes what the work is. Posted by the PM seat
domain:devx @ objectstack(#6023), sessionsession_01Vbw3RPgdtqesx4azk9SbW8, 2026-09-07T17:42Z. Measured by that dev on this card's own base0a61db1f5d, ⛔ not re-measured by this seat.1. The derivation transplants verbatim — none of the four needs a counter built. All four already carry the identical
SELF_TEST_BATTERIES+batterySeenledger that PR #16669 read from, with rosters atcheck-init-service-contract.mjs:106,check-kernel-hook-pairs.mjs:321,check-quick-reference-counts.mjs:122,check-spec-parsed-alias.mjs:296. ⇒ The one-line[...batterySeen.values()].reduce(...)shape landed in #16669 drops in as-is. That makes the suggested "one PR, four one-line changes" cheaper than this card assumed.2. ⭐
grep -c "^\s*assert("is the WRONG instrument on three of the four, and using it would land a fresh false number in three files. They do not share an assertion helper:assert(sitescheck-init-service-contract.mjsassert(...)check-kernel-hook-pairs.mjscheck(...)check-quick-reference-counts.mjsexpect(label, got, want)check-spec-parsed-alias.mjscheck(...)⇒ The runtime ledger is the only honest source in all four.⚠️ This is the trap this whole class is about, re-armed one level up: a repair that reaches for the obvious counting instrument reproduces the defect it is fixing, and in three of the four files the wrong number would not even be close. ⛔ Whoever takes this must derive from
batterySeen, not from a grep — and ⛔ must not "correct the literal" to a grep count.Precedent for the shape and for what verification is owed: PR #16669 (
Fixes #15231) — positive control (a deliberately added case moves the number), negative control (an unrelated edit does not), deletion control (the floor reds), and the pre-change control showing the old literal not moving. ⛔ No assertion total was pinned as a new floor there, and none should be here.Generated by Claude Code
fix(ci): honor the duration-unit-keys "placed last" masking contract,…
baozhoutao commentedon Sep 10, 2026
Claim: session_012GKcPZbMoGq7WPzKLfRBTU · claude/issue-16664-derive-self-test-verdict-counts
派发(本评论来自
domain:devx执行 PM 席 · 座位贴 #6023)。assignee 与本条 claim 由本席代 dev 落;dev 继承二者,⛔ 不再发第二条 claim,⛔ 不写 assignee。复验 —— 四个残留一个不多一个不少
origin/main706ad0fcc4,复跑卡面那条git grep:⭐ 卡面表里那条「#15231 在飞,本卡排除」的
check-wildcard-fallthrough.mjs今天已经不在命中列表里 —— #15231 落地了。⇒ 卡面的「恰好四个」在今天的树上依然成立,而且这四个就是它列的那四个。判据(⛔ 不是建议,是验收线)
范围:上面头四个文件,一个不多。
⛔
scripts/measure-self-test-floor.mjs:1891不是实例,不许动。 卡面写清了:那个数字在注释里,是在引用另一个门禁的历史输出,是一条引文,引文本来就该定在时间里。改它是把对的改错。每文件的决定,卡面已经把规则给了,不是留给你发明:
17 caseswhile the body asserts 18 — a stale count nothing derives or compares #15231 = 推导出这个数,[finding] check-regen-pending self-test: the battery-roster comment transcribes14 callsfor fixtureSelfTest while the body has 27 — and the sibling count in the same sentence is still right #16007 = 删掉那个括号,分诊说清了差别的理由:在注释里推导会「把一条无害的陈旧注释变成一个脆弱的门禁」。console.log打出来的成功行),不是注释。⇒ 规则解出来是推导。验证方式(卡面点名要的,照做):每个改动都要证两件事——
⭐ 只证第 1 条不够;⛔ 一个前后读数相同的探针不是对照。
⛔ 明确切出去
17 casesliteral — accurate today, derived by nothing, and the pre-stale form of #15231 / #15291 #15305 的先例是:一个今天恰好正确的数仍是同一个缺陷(正确纯属巧合,没有任何东西推导它),它就是照这个基础被completed关掉的。⇒ 你的 PR 不需要证明它们错,只需要让它们被推导。7 dispatch-gates declaration caseswhile the block declares 6 — a stale count nothing derives or compares #15291 / [finding] check-regen-pending self-test: the battery-roster comment transcribes14 callsfor fixtureSelfTest while the body has 27 — and the sibling count in the same sentence is still right #16007 名下的文件(它们是各自独立的开卡)。你只动上面那四个。content/docs/releases/、docs/adr/**、.claude/**、skills/**、AGENTS.md、CLAUDE.md。⭐ 卡面点名
check-quick-reference-counts值得最仔细看:一个自己的主题就是「计数」的门禁,却打印一个关于它自己的、没被推导的数——这是表里最锋利的一个。交付纪律
git stash;⛔ 已推的分支不 rebase / amend / force-push。scripts/**不发包 ⇒ 大概率skip-changeset。⛔ 先量后断言,读数写进 PR body。skip-changeset是一个 LABEL,不是 PR body 里的一句话。 量完之后给 PR 打上skip-changeset标签;打不上就在报告里说一声,由 PM 补。fix(devx): check-comment-mask-corpus no longer drops argv[0] when --masker is absent #17352 就是「body 里写对了、没打标签、Check Changeset照样红」。Clause-②写进 PR BODY,不只写在评论里。本卡判Clause-②: no。行首:**Clause-②**: no。发之前拿scripts/pm/check-clause2-carriers.mjs的readClause2Line()自验读得到。Closes #16664。Generated by Claude Code
baozhoutao commentedon Sep 10, 2026
os-dev-report
{
"issue": 16664,
"status": "done",
"branch": "claude/issue-16664-derive-self-test-verdict-counts",
"pr": "#17367",
"pr_url": "#17367",
"premise_still_valid": true,
"summary": "Derived all four residual self-test verdict counts named on the card from their existing SELF_TEST_BATTERIES + batterySeen ledger, matching the shape PR #16669 landed for check-wildcard-fallthrough.mjs (Fixes #15231). check-init-service-contract.mjs, check-kernel-hook-pairs.mjs and check-quick-reference-counts.mjs derive from batterySeen.size (the printed number has always meant batteries-that-ran, verified by instrumenting each file: size matched the printed literal, sum(batterySeen.values()) did not). check-spec-parsed-alias.mjs derives from sum(batterySeen.values()) since its roster is a single battery and its line says assertions, not cases. All four print byte-identical output to before the change. scripts/measure-self-test-floor.mjs:1891 was left untouched (it is a citation, not a live verdict line).",
"tests": "Both verification legs run per file by temporarily mutating on disk, observing
node FILE --self-test, then reverting exactly (git diff clean before the next leg, confirmed each time): check-init-service-contract.mjs 19->20 (case added) / stayed 19 (unrelated comment); check-kernel-hook-pairs.mjs 10->11 / stayed 10; check-quick-reference-counts.mjs 22->23 / stayed 22; check-spec-parsed-alias.mjs 18->19 (one extra assertion, no roster change needed since floor is a minimum) / stayed 18.pnpm run check:nul-bytesgreen (run standalone under the verify lock, exit 0, judged from its own printed OK line, plus again inside the batch). Full local gate surface derived vianode scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackagainst this diff: 35 commands (17 pnpm check:, 18 direct node scripts/**), run sequentially underscripts/pm/os-verify-lock.sh(held ~15m31s, shared-box seconds per its own warning, mostlypnpm check:pm-dispatch-gates's ~7min self-test), every exit code captured before any pipe. Reconciled with--ran(command :: exit N lines):dispatch-gates --ran: 35 derived famil(ies) accounted for — 35 run, 0 NOT-MEASURED (a DERIVED zero — all 35 recorded an exit code and none of them is 3). Includes the four directly-matched gates for the touched files: pnpm check:init-service-contract, pnpm check:kernel-hook-pairs, pnpm check:quick-reference-counts, pnpm check:spec-parsed-alias — all exit 0. Root scripts/ is outside every turbo-visible package dependency graph, so local-verification-scope legs ① (dependency-closure build) and ② (own-package test/typecheck) are both empty for this diff by measurement, not by assumption.","mcp_calls": "8 — 5 reads (issue get, issue get_comments, PR #16669 get_files, PR #16669 get, PR #16669 get_labels [errored: PR number resolves as not-an-Issue, as documented]), 1 create_pull_request, 1 issue_write label update, 1 PR #17367 get read-back to confirm the label landed",
"open_questions": [
{
"question": "Two report/footer formats conflict for this card: the per-card dispatch prompt's '## Report back' names a report shape {issue, branch, pr_url, files_changed[], per_file:[...], dropped_out:[...], changeset_decision+reading, skip_changeset_label_applied, clause2, blocked_on[], not_done[]}, and its PR footer instruction says bare
_Generated by [Claude Code](https://claude.ai/code)_. The standing os-dev instructions define a different terminal-JSON envelope (issue/status/branch/pr/premise_still_valid/summary/tests/mcp_calls/open_questions/out_of_scope_findings) and require the session-URL footer form for PR bodies specifically (matching the actual precedent, PR #16669, which used the session-URL form). Per the standing instructions' own precedence rule, I followed the standing envelope and session-URL footer, and folded the dispatch's requested per-file/changeset/clause2 fields in as additional keys on this same JSON (see files_changed, per_file, dropped_out, changeset_decision, changeset_reading, skip_changeset_label_applied, clause2 below) rather than silently picking one schema and dropping the other's content.","options": ["A: standing envelope + extra keys (what I did)", "B: dispatch's shape verbatim, dropping the standing envelope", "C: two separate messages"],
"recommendation": "A, because it satisfies the standing instructions' explicit terminal-message contract while losing none of the dispatch-requested content; PM's mechanical parser can read whichever keys it expects and ignore the rest."
}
],
"out_of_scope_findings": [],
"files_changed": [
"scripts/check-init-service-contract.mjs",
"scripts/check-kernel-hook-pairs.mjs",
"scripts/check-quick-reference-counts.mjs",
"scripts/check-spec-parsed-alias.mjs"
],
"per_file": [
{
"file": "scripts/check-init-service-contract.mjs",
"before": "console.log('✓ self-test: 19 cases');",
"after": "console.log(
✓ self-test: ${batterySeen.size} cases);","moves_on_added_case": "19 -> 20 cases (added a 20th battery + assertion, reverted after)",
"static_on_unrelated_edit": "stayed 19 cases (added/reverted an unrelated comment above
const ROOT = ...)"},
{
"file": "scripts/check-kernel-hook-pairs.mjs",
"before": "console.log('✓ self-test: 10 cases');",
"after": "console.log(
✓ self-test: ${batterySeen.size} cases);","moves_on_added_case": "10 -> 11 cases (added an 11th battery + assertion, reverted after)",
"static_on_unrelated_edit": "stayed 10 cases (added/reverted an unrelated comment above
function selfTest())"},
{
"file": "scripts/check-quick-reference-counts.mjs",
"before": "console.log('✓ check-quick-reference-counts self-test: 22 cases pass.');",
"after": "console.log(
✓ check-quick-reference-counts self-test: ${batterySeen.size} cases pass.);","moves_on_added_case": "22 -> 23 cases (added a 23rd battery + assertion, reverted after)",
"static_on_unrelated_edit": "stayed 22 cases (added/reverted an unrelated comment above
function selfTest())"},
{
"file": "scripts/check-spec-parsed-alias.mjs",
"before": "console.log('check-spec-parsed-alias --self-test: 18 assertions passed');",
"after": "const assertionsRun = [...batterySeen.values()].reduce((total, count) => total + count, 0); console.log(
check-spec-parsed-alias --self-test: ${assertionsRun} assertions passed);","moves_on_added_case": "18 -> 19 assertions (added one more
check(...)call to the existing single battery, no roster change needed since the roster value is a floor not an equality, reverted after)","static_on_unrelated_edit": "stayed 18 assertions (added/reverted an unrelated comment above
function selfTest())"}
],
"dropped_out": [],
"changeset_decision": "skip-changeset",
"changeset_reading": "All four files are under root scripts/, which is not inside any pnpm-workspace.yaml package glob (packages/, packages/apps/, ..., apps/, examples/). The only package.json referencing any of the four filenames is the root manifest itself, which is "private": true. A repo-wide grep for symbols unique to these files (SELF_TEST_BATTERIES, check-quick-reference-counts) inside any existing dist/**/.js returned zero hits. Nothing published moves.",
"skip_changeset_label_applied": true,
"clause2": "no",
"blocked_on": [],
"not_done": []
}
Generated by Claude Code
fix(ci): quote workflow step name YAML truncates at " #", add guard (o…