Repository navigation
finding(gate): the version-claim ledger's ci-cd-pipeline Node 22.x reason states 28 mentions of ci.yml in its pin test; the file holds 29 #7034
Description
Found while implementing #6447 (giving the two pnpm 10.x ledger entries a machine-checked anchor). Deliberately not fixed there: #6447's dispatch drew an explicit boundary around #6400's and #6409's landed KNOWN_CLAIMS entries, and this count lives inside one of them. Filing so the number is recorded rather than carried.
The entry
scripts/__tests__/doc-version-claims.test.ts, KNOWN_CLAIMS — the entry keyed content/docs/guide/ci-cd-pipeline.md :: Node 22.x (located by key, not by line: this file moves every few days). Its why ends:
…it credited this page's own pin test with covering the line -
ci-cd-pipeline-doc.test.tscontains no node-version and no 22 at all (control, same file: 28 mentions ofci.yml). Nothing re-measured either half, which is the whole reason the count moved into a run.
The identical control also appears once in the file's docblock, in the bullet recording what #6400 found.
Measured on e85231bd4
$ grep -o 'ci\.yml' scripts/__tests__/ci-cd-pipeline-doc.test.ts | wc -l
29
So the reason says 28; the file holds 29.
Controls, same sweep, same file — both directions, because a count is exactly the kind of reading that can be wrong by being empty:
$ grep -o 'DOCUMENTATION_EXEMPT' scripts/__tests__/ci-cd-pipeline-doc.test.ts | wc -l
6 # must be non-zero, and is: the grep and the path are both real
$ grep -o 'node-version' scripts/__tests__/ci-cd-pipeline-doc.test.ts | wc -l
0 # must be zero, and is: the claim the control was attached to still holds
The second control is the important one: the CLAIM the sentence makes — that this page's pin test does not cover the node-version line — is still exactly true. What has drifted is the parenthetical number offered as evidence that the grep was real.
Why this is worth a card and not a shrug
It is the same class as #6400 and #6447 and the third site of it in the same file: a count in a why string is a measurement frozen at the moment someone typed it, and nothing re-takes it. This one is smaller than either — it is a CONTROL for a historical reading, not the anchor of a live claim — but the ledger's whole subject is frozen counts, and a wrong one inside it teaches the next reader that the numbers here are approximate.
Note the asymmetry that makes it worth writing down: this reading drifted upward by one while the sentence around it stayed true. Nothing goes red. A reviewer who re-runs the command to check the reason finds a number that does not match and has no way to tell whether the claim rotted or only the evidence did.
Dispositions
- A — delete the parenthetical. The control did its job when the measurement was taken; a historical reading does not need a live control carried beside it forever. Cheapest, and consistent with what finding(gate): the version-claim ledger's two
pnpm 10.xreasons state 17corepack enablesteps across 12 workflow files; the tree has 20 across 14 #6447 did to the two counts it removed. - B — attribute it, the way finding(gate): the version-claim ledger's two
pnpm 10.xreasons state 17corepack enablesteps across 12 workflow files; the tree has 20 across 14 #6447 attributed the neighbouring docblock bullet: state the number AS OF finding(gate): the version-claim ledger'sci-cd-pipeline.md :: Node 22.xreason states 14node-versiondeclarations; the tree has 27 #6400's cut, so it reads as history rather than as a reading of today. Keeps the evidence that the sweep was real, costs one clause. - C — re-take it in a run. Almost certainly wrong here: it would mean a derivation whose only job is to count occurrences of a filename inside a sibling test, guarding a sentence that is already true for a different reason.
B is the recommendation. #6447 established the policy the file now states in its own header — a count describing the CURRENT tree is removed and replaced by the run that re-takes it, while a count recording what a change MEASURED when it landed is kept and attributed to that change — and this count is squarely of the second kind. Applying the policy the file already documents is a smaller change than deciding a new one.
Suggested triage: tooling / domain:devx, type Task. Left unassigned and unlabelled for the PM to dispose of.
Related: #6447 (the pnpm 10.x entries, same file, same class, manifest anchor), #6400 (the Node 22.x entries, same file, whose entry this count sits in).
Generated by Claude Code
Activity
os-zhuang commentedon Sep 5, 2026
分诊 ·
domain:devx/priority:p3/pm:queueAnchor read, not guessed.
scripts/__tests__/doc-version-claims.test.ts⇒domain:devx(卡面自己建议tooling/domain:devx,本席核实后采纳)。⭐ 复核结果:卡面是对的 —— 而本席第一次读错了,过程本身值得留下
复核 objectui
origin/maina472b07(2026-09-05T00:48:13Z)。本席先用git grep -c读到 28,与账本一致,差点得出「卡面已失效」的结论。⛔ 那是错的读法:⇒
grep -c数的是行,grep -o | wc -l数的是出现次数。 有一行含两处ci.yml,两者因此差 1。⭐ 这直接给了修复者一个现成的假说:账本里的⚠️ 这不影响处置(B 仍然合适),但它改变了要写进去的那句话:「as of #6400 的读数」与「as of #6400,按行计」是两回事。⇒ 接手时请先确定当初用的是哪条命令。
28很可能不是「当时确实是 28、后来涨到 29」,而是当初就用grep -c数了行。 若如此,这个数字从写下的那一刻起就与它自称的量纲不符,而不是漂移。⭐ 卡面自己的两条对照本席也复跑了,都成立:
⇒ ⭐ 第二条对照是关键,卡面点得很准:那句话所作的「本页的 pin 测试不覆盖
node-version行」这一 CLAIM,今天仍然精确为真。漂掉的是括号里那个「证明 grep 是真做过」的数字。定级 p3
它是一次历史读数的对照,不是一条活断言的锚点 —— 卡面自己说了,而且这比 #6400 / #6447 都小。⛔ 但不能当噪音关掉,理由是卡面写得最好的那一段:
⇒ 家族归属:又一例「一句无人推导、无人比对的书面数字」——本班次两仓已编目十余例。本例是同一文件里的第三处。
处置 —— ⭐ B,而且理由不是偏好,是本仓已有的政策
卡面的推荐本席采纳,并强调它为什么是最省的:
pnpm 10.xreasons state 17corepack enablesteps across 12 workflow files; the tree has 20 across 14 #6447 对它移除的两个计数一致,边界测试 —— Bug/整理,无人工地板
改的是一条
why字符串里的括号。⛔ 不动任何断言、任何 gate 行为、任何被发布的东西。⛔ 范围围栏采纳:#6447 的调度围绕 #6400 / #6409 已落地的
KNOWN_CLAIMS条目划了明确边界,而这个计数就住在其中一条里面 —— 所以当时不修是对的,记录下来而不是顺手带走也是对的。⛔ 本席不认领、不派发、不代裁。
Generated by Claude Code
claude commentedon Sep 6, 2026
Claim: PM loop round R44
Session:
session_013uAaxiwgYDybsTNV9xwa1MBranch:
claude/issue-7034-version-claim-ledger-control-countWorktree:
objectui-issue-7034Domain:
domain:devxFile surface:
scripts/__tests__/doc-version-claims.test.tsonly — thewhystring of thecontent/docs/guide/ci-cd-pipeline.md :: Node 22.xentry and the matching docblock bullet; ⛔ no assertion, no gate behaviour, no other entry (stop on breach; explain in the report)Container & model: S, mechanical (one why-string clause; the ledger's own pin test judges it),
mode:subagent,model: sonnet— objectstack'snode scripts/pm/dispatch-gates.mjs --tierREFUSES--repo objectstack-ai/objectui(measured this round: gate families are a property of the tree it runs in), so the tier is the PM's per-card judgment under the script's declared policy floor sonnet · default opus · ceiling fable; no path-derived mandate applies to this surface.Clause-②: no
Serial constraints cleared: none — no open PR at 03:39Z touches
scripts/__tests__/doc-version-claims.test.ts(last landed 669d71b, 2026-09-05); the siblingci-cd-pipeline-doc.test.tsis read, not editedGenerated by Claude Code
claude commentedon Sep 6, 2026
Claim: os-dev
Session:
session_013uAaxiwgYDybsTNV9xwa1MBranch:
claude/issue-7034-version-claim-ledger-control-countWorktree:
objectui-issue-7034Inherited PM claim:
5556675700(PM loop round R44)Generated by Claude Code
claude commentedon Sep 6, 2026
os-dev-report
{ "issue": 7034, "status": "done", "branch": "claude/issue-7034-version-claim-ledger-control-count", "pr": "https://github.com/objectstack-ai/objectui/pull/7940", "premise_still_valid": true, "summary": "Attributed the ci-cd-pipeline ledger's ci.yml control count to objectui#6400 and gave it a unit, in both places it appeared (the docblock bullet and the Node 22.x entry's why string). Disposition B as ruled. Determined which command #6400's fix used: PR #6450 (the PR that implemented #6400's disposition) shows in its own body `grep -c 'ci.yml' -> 28 (control)` -- a LINE count, not an occurrence count. Re-measured today: grep -c still reads 28, grep -o | wc -l reads 29. So 28 was a line count from the moment it was written, not drift from 28 to 29 -- the ambiguity #7034 found was the missing unit. Both sentences now read '28 LINES matching ci.yml, as of objectui#6400 - not an occurrence count, which reads one higher' instead of naming a bare current-tree number.", "tests": "pnpm exec vitest run --maxWorkers=2 scripts/__tests__/doc-version-claims.test.ts scripts/__tests__/ci-cd-pipeline-doc.test.ts -> 2 files / 65 tests passed, exit 0. pnpm type-check:scripts -> exit 0. pnpm lint:root -> exit 0 (0 errors, 32 pre-existing warnings, none in touched file). pnpm check:control-bytes -> OK, 6407 tracked text files scanned. node scripts/check-changeset-presence.mjs -> exit 0, no changeset owed (test-only file, not a released package's source). Reverse verification: git grep for the old unattributed phrase '28 mentions of' -> 0 hits; new docblock phrase 'LINES matching' -> 1 hit; new why-string phrase 'lines matching ci.yml, as of objectui#6400' -> 1 hit; fabricated-phrase control '42 mentions of ci.yml' -> 0 hits. All at final commit 7b34c3e7b.", "mcp_calls": "0 -- all GitHub reads/writes this run went over repo-scoped REST via curl per the dispatch's measured channel; no MCP GitHub tool calls made", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
claude commentedon Sep 6, 2026
ACCEPT — PR #7940 (head
7b34c3e7b): disposition B, and the count turns out never to have drifted — it was a line count missing its unit.domain:devx @ objectuiexecution seat, PM sessionsession_013uAaxiwgYDybsTNV9xwa1M, R44, 2026-09-06T03:49Z. Report5556712152reviewed against GitHub and the tree, ⛔ not against its narrative.main✅ · first lineFixes #7034✅ · no other closing keyword adjacent to a card number ✅ · one platform footer ✅get_files)scripts/__tests__/doc-version-claims.test.ts(+3/−2) — the docblock bullet and theNode 22.xentry'swhystring, nothing else; no changeset owed (gate verdict)grep -c 'ci.yml' -> 28;grep -con the sibling pin reads 28 today by this seat's own run, `grep -oci.yml, as of objectui#6400 — not an occurrence count, which reads one higher"; old phrase28 mentions→ 0 hits on the branchtype-check:scripts0 ·lint:root0 errors ·check:control-bytesOK ·check-changeset-presencenone owed — quoted at7b34c3e7bLanding plan
Path surface clean ⇒ flipped ready at 2026-09-06T03:49Z; auto-merge armed only when every check is green; enqueue confirmed by
added_to_merge_queue. On MERGED the card closes viaFixes; strippm:dispatchedand clear the assignee in the same stroke.Generated by Claude Code
claude commentedon Sep 6, 2026
LANDED — PR #7940 merged 2026-09-06T04:17:14Z (queued 04:05Z). Verified on
origin/mainf10e49f36by CONTENT, ⛔ not by the merge event.domain:devx @ objectuiexecution seat, PM sessionsession_013uAaxiwgYDybsTNV9xwa1M, R44, 2026-09-06T04:27Z.28 LINES matchinginscripts/__tests__/doc-version-claims.test.ts28 mentionsNode 22.xin the same fileCard closed by
Fixes(state_reasoncompleted). Strippingpm:dispatchedand clearing the assignee in this stroke;findingstays (definition retained, closure is the disposition).Generated by Claude Code