Repository navigation
Description
Found while verifying stack card 3/6 of #14478 (branch claude/issue-15678-kernel-duration-unit-in-key-name, head 8f2b8f389). Filed rather than fixed: the defect belongs to card 1/6's diff, whose branch is still open, and repairing another card's diff from this one is the shape the scope rules forbid.
The two reds
Both measured on the stacked head, exit code captured before any pipe:
$ pnpm --filter @objectstack/spec check:llms-txt # EXIT=1
✗ packages/spec/llms.txt — the file advertises things this package does not have:
packages/spec/llms.txt:94 [count] domain `shared` declares 13 schemas; src/shared/ holds 14
packages/spec/llms.txt:80 [count] heading declares 207 schemas; packages/spec/src/ holds 208
$ pnpm check:quick-reference-counts # EXIT=1
✗ content/docs/getting-started/quick-reference.mdx — the declared sections do not match the page or the reference tree:
content/docs/getting-started/quick-reference.mdx:209 [total] section "Shared Protocol" declares "of 8 schemas" but content/docs/references/shared/ publishes 9 page(s)
One cause, two gates
Both counts moved by the same commit. 3f9544447 (card 1/6 of #14478, branch claude/issue-15676-epoch-ms-and-external-vocabulary-exemptions) added:
packages/spec/src/shared/epoch.zod.ts— the sharedEpochMsschema, which tooksrc/shared/from 13 to 14 and the tree from 207 to 208;content/docs/references/shared/epoch.mdx— its generated reference page, which took that directory from 8 pages to 9.
Neither count is generated. llms.txt is hand-kept by design (its header records that there is deliberately no gen:llms-txt, because the number is not the claim — the prose beside it is), and the quick-reference.mdx section headings are hand-written too. So a new schema file in a domain is exactly the change that has to move them by hand, and this one did not.
Attribution evidence
Both gates read files that card 3/6's branch does not touch:
$ git diff --name-only b4633903b..HEAD -- packages/spec/src/shared # 0 files
$ git diff --name-only b4633903b..HEAD -- content/docs/references/shared # 0 files
$ git log --oneline -1 -- packages/spec/src/shared/epoch.zod.ts
3f9544447 feat(spec): publish the externalVocabulary standard on the reference page (#15676)
$ git log --oneline -1 -- content/docs/references/shared/epoch.mdx
3f9544447 feat(spec): publish the externalVocabulary standard on the reference page (#15676)
Card 3/6 adds no schema file at all — its only new sources are ADR-0087 registry entries under packages/spec/src/migrations/entries/, which neither gate counts.
Why this is worth a card rather than a note
Heavy CI does not run on a stacked PR: both lint.yml and ci.yml declare pull_request: branches: [main], so neither of these gates reports on any head in this stack. They will first go red at the moment the stack lands on main — on every PR in the repo at once, not just this stack's. Whoever repairs it then will be reading a red that names shared and epoch with no obvious connection to the duration-key campaign that introduced it.
The fix
Correct the numbers and re-read the prose beside each one, per the check:llms-txt header: rewriting a count without re-reading its row turns a loud staleness into a silent lie. Three edits:
packages/spec/llms.txt:94—shareddomain, 13 → 14;packages/spec/llms.txt:80— heading total, 207 → 208;content/docs/getting-started/quick-reference.mdx:209— "Shared Protocol", 8 → 9.
Best landed on card 1/6's own branch so the stack is green as one unit; the alternative is a follow-up lap after the stack merges, which is strictly worse because the red is then on main.
Related: #14478 · #15676 · #15678. No assignee — for triage.
Activity
os-sales commentedon Sep 5, 2026
Repaired on card 1/6's own branch, as this report recommended:
claude/issue-15676-epoch-ms-and-external-vocabulary-exemptions, head5b1b5308e(PR #15814, still draft — a human lands it). Not closing this card: it closes when that branch lands.Your three sites, all confirmed on my own tree before editing, and all three counts re-derived after:
packages/spec/llms.txt:94shareddeclares 13packages/spec/llms.txt:80content/docs/getting-started/quick-reference.mdx:209Both reds reproduced verbatim on
960580850before the edit and both read exit 0 after, on the same tree, built first:Two judgement calls worth recording here, since this card is where the next reader will look:
quick-reference.mdxmoved M only. N stays 5 and no row was added for the epoch page: that page's own "Reading the counts" paragraph declares the tables a curated subset, and the gate's guidance says closing the gap is a decision rather than a fix.llms.txtprose moved with the number, per that gate's header. Thesharedrow's third cell characterises the domain, soEpoch Instant (EpochMs)was added to it; bumping 13 to 14 beside a sentence that did not mention the schema which moved it is the silent lie the header warns about. The heading's own paragraph needed no change.The same push also corrected four JSDoc
@exampleblocks on that branch that still taught the keys it tombstoned (WebSocketEvent.timestamp->occurredAttwice,HealthStatus.timestamp->checkedAttwice) — same defect class, no gate reads them. Details in the PR comment.Generated by Claude Code
os-zhuang commentedon Sep 6, 2026
分诊:
domain:spec+domain:devx/bug+tooling/pm:queue/priority:p3本卡是在 stack 尚未落地时填的("the defect belongs to card 1/6's diff, whose branch is still open")。那个 stack 已于 2026-09-06T03:17Z 落到
main(e9fcd6bbd)。本席逐条重测:llms.txt:94—shared声明 13,src 有 14| shared | 14 | … Epoch Instant (EpochMs) |;git ls-tree packages/spec/src/shared/ | grep -c '\.zod\.ts$'= 14quick-reference.mdx:209— "Shared Protocol" 声明 8,目录发布 9:208 ## Shared Protocol (5 of 9 schemas);content/docs/references/shared/有 10 个.mdx,其中一个是index.mdx⇒ 非索引页 = 9index.mdx与meta.json——卡片当时报「publishes 9」而彼时非索引页正是 9,与此一致)llms.txt:80— 标题声明 207,src 有 208:80 ## 3. Schema Inventory by Domain (205 schemas)第三条为什么本席不下结论:本席对
packages/spec/src全树数.zod.ts得 206,与标题的 205 差一。但 206 是原始文件计数,不是门的谓词——卡片当时报的是「标题 207 / src 持有 208」,而当时的文件数必然少于今天,⇒ 门数的不是.zod.ts文件个数(它可能数导出的 schema、可能排除某些文件)。⛔ 用本席的 206 去断言 205 是错的,正是本 lane 一整天在追的那个失败类——拿一个不同的谓词去判另一个谓词的读数。因此本卡的处置是核验并关闭,不是修复
关闭条件(写死,供承接席直接执行):
completed关闭,并在关闭评论里贴出两条 verdict 行。llms.txt:80的 205。 它可能已经是对的。定级理由
packages/spec/llms.txt⇒domain:spec;content/docs/getting-started/quick-reference.mdx⇒domain:devx。若最终只剩llms.txt一处待修,承接席可删掉domain:devx。bug+tooling:两处手工计数与树不符 ⇒ 有东西是假的(若仍成立)。修复不拓宽接受集 ⇒ Bug/tidy 侧,无人工地板。⭐ 卡片里不随时间失效的两条,本席提出来留存
① 修数字必须连同重读它旁边的散文。
⭐ 这句话本席逐字背书,并指出它已经在本轮别处得到印证:#16136(
book.json头部同时写错了总数、dead 的基数、并手工枚举了 dead 集合)与 #16135(translation.json的 WALK BOUNDARY 普遍量化对一个组为假)都是同一形状。llms.txt的档头自陈刻意没有gen:llms-txt,理由正是「数字不是主张,旁边的散文才是」——⇒ 只改数字等于把门的意义抽空。② 卡片的归因证据方法值得记名。 它没有说「大概是 card 1/6 干的」,而是用四条命令证明:本分支对两个被计数目录的 diff 都是 0 文件;两个新增文件的最后一次提交都是
3f9544447(card 1/6);且 card 3/6 根本没加任何 schema 文件(它的新增源文件全在packages/spec/src/migrations/entries/下,两个门都不数)。⇒ 归因是测出来的,不是推出来的。Related:#14478(stack,已落地
⚠️ 卡片提到的「重型 CI 不在 stacked PR 上跑」这一事实,本轮已由 #16149 第 3 项独立测量并立卡(
e9fcd6bbd)· #15676(card 1/6,引入两处计数变化的提交3f9544447)· #15678(card 3/6,撞见它的那一轮)。lint.yml/ci.yml均声明pull_request: branches: [main])——本席已把它路由为domain:devx/needs-user-decision/ p3,并建议把第 3 项单独拆出按 p2 处理。⛔ 两卡不重复:本卡是具体的两个计数,那张是机制。⛔ 本席为 triage 席位:不认领、不派单、不写码、不合并、不裁决 decision-box(本会话为
claude-opus-5,CONTRACT_REVIEW_TIER硬门要求 fable)。Generated by Claude Code
claude commentedon Sep 6, 2026
Claim: PM loop round 1
Session:
session_01Vbw3RPgdtqesx4azk9SbW8Branch:
claude/issue-15904-count-gates-verifyWorktree:
objectstack-issue-15904Domain:
domain:devx(co-labelleddomain:spec:packages/spec/llms.txtis the spec seat's — this dispatch VERIFIES only; if thellms.txtcount is red, it stops and reports, it does not edit spec)File surface: verification only —
content/docs/getting-started/quick-reference.mdxis the one file this lane may edit if its count is red (stop on breach; explain in the report)Container & model:
Smechanical (run two gates, report their verdict lines),mode:subagent,model: sonnet—node scripts/pm/dispatch-gates.mjs --tierat33388f9(05:42Z): no path-derived mandate, floor sonnet · default opus · ceiling fableClause-②: no
Serial constraints cleared: none — open-PR file map taken 2026-09-06T05:41Z: no open PR touches either file. Stack #14478 landed on
main(e9fcd6bbd, 03:17Z) per triage5557089047.Expected outcome per triage: both gates exit 0 ⇒
premise_still_valid: false, no PR, card closescompletedon the verdict lines.Generated by Claude Code
claude commentedon Sep 6, 2026
os-dev-report
{ "issue": 15904, "status": "done", "branch": "claude/issue-15904-count-gates-verify", "pr": null, "premise_still_valid": false, "summary": "Verify-first card. Re-ran both gates on a fresh origin/main worktree (HEAD 0c5d0359, which has e9fcd6bbd \u2014 the #14478 stack merge \u2014 as an ancestor, confirmed via git merge-base --is-ancestor exit 0). check:llms-txt exits 0: 205 schemas matches the heading, resolving the third count that triage 5557089047 explicitly left undetermined. check:quick-reference-counts exits 0: 13 sections, every (N of M schemas) heading matches its table and content/docs/references/. Per the triage's closure condition, both exit 0 means the card closes completed with no PR and no edits. No file changed (git status/diff against BASE both empty). Empty branch pushed first as the write-routing probe (no 403), then removed along with the worktree since no PR was opened.", "tests": "gates: `pnpm --filter @objectstack/spec check:llms-txt` -> EXIT=0 -> own verdict: \"check-llms-txt self-test: 21 cases pass.\" / \"packages/spec/llms.txt: 97 claim(s) re-derived \u2014 every advertised symbol resolves against api-surface/ (17 entry points), every subpath is a real `exports` key, the inventory matches src/ (14 domains, 205 schemas) and the package table matches the workspace (68 published).\"; `pnpm check:quick-reference-counts` -> EXIT=0 -> own verdict: \"check-quick-reference-counts self-test: 22 cases pass.\" / \"content/docs/getting-started/quick-reference.mdx: 13 section(s), every (N of M schemas) heading matches its table AND content/docs/references/ (14 categories, all sectioned or declared).\" Both run under the shared verify lock (OS_VERIFY_LOCK_SLOT=issue-15904), exit captured before any pipe (`cmd > out 2>&1; EXIT=$?`). origin/main sha run on: 0c5d03596d7936027d390f153b85f6b11d8b4271. Neither gate needed a build (both are tsx/node scripts reading packages/spec/src and content/docs directly, not dist) -- A1's PREREQUISITE NOT MET path did not apply. Per A2, did not reason from raw .zod.ts file counts (206 total, 14 under shared) -- only the gates' own verdict lines were read as the predicate.", "mcp_calls": "0 -- used repo-scoped REST (curl) for issue body/comments per the routing steer; no MCP GitHub tool calls made this run", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
claude commentedon Sep 6, 2026
ACCEPT — premise falsified, card closes
completedwith no PR. PM seatdomain:devx @ objectstack, sessionsession_01Vbw3RPgdtqesx4azk9SbW8, 2026-09-06T06:0xZ.Reviewed against the report comment
5557300491(first lineos-dev-report, intact on read-back) and cross-checked on a re-fetchedorigin/main:pnpm --filter @objectstack/spec check:llms-txt→ EXIT=0, own verdict line: "packages/spec/llms.txt: 97 claim(s) re-derived — … the inventory matches src/ (14 domains, 205 schemas) …". Cross-check:packages/spec/llms.txt:80onorigin/mainreads(205 schemas)— the third count triage5557089047left undetermined is the gate's own number, not a file count.pnpm check:quick-reference-counts→ EXIT=0, own verdict line: "content/docs/getting-started/quick-reference.mdx: 13 section(s), every (N of M schemas) heading matches its table AND content/docs/references/ …".origin/main0c5d03596, which carries the spec: duration-shaped number keys carry their unit in describe prose only — twottlkeys with different units in one block, baretimeoutkeys, unit-less tenant timeouts #14478 stack mergee9fcd6bbdas an ancestor (merge-base --is-ancestorexit 0). Exit codes captured before any pipe; both under the shared verify lock.files_changed: none; deviations: none; the empty probe branch was removed after the run.Per triage's closure condition (both exit 0 ⇒ close
completedwith the two verdict lines), closing now.pm:dispatchedstripped and the assignee cleared in this same stroke;domain:devx/domain:spec/bug/tooling/priority:p3stay (ownership, not state). The three counts named by the card are all correct onmaintoday; the fix landed with the stack (comment5552441055).Generated by Claude Code