You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[finding] check:generated truncates a failing gate's per-shard list to 3 lines with no marker, so a sample reads as a complete inventory #19015
Filed by the domain:spec PM seat from the base-catch-up round on card #18063 / PR #18890. Measured by that round with a mutation probe, ⛔ not inferred. It blocked nothing — the gate's verdict, exit code and remedy are all correct. What is wrong is that its per-shard list LOOKS like an inventory and is a sample.
What happens
packages/spec/scripts/check-generated.ts:656 truncates a FAILING gate's captured output to its first three non-empty lines:
.slice(0, 3)
So when check:api-surface-declarations fails inside the check:generated aggregate, the aggregate prints up to three lines of it. The round that found this saw data.txt and two entries — while contracts.txt was equally stale and four more declarations had moved.
⇒ A reader who takes the aggregate's shard list as the set of stale shards regenerates less than is stale, or reasons about a delta that is larger than what was shown.
⛔ What is NOT wrong — state it so nobody over-fixes this
The verdict is right: the aggregate fails when a member gate fails.
The remedy it prints is complete — it names the family-level gen: command, which regenerates every shard, not the three that happened to print.
The standalone gate is not blind. The round proved this rather than assuming it: it reverted contracts.txt alone to its merged-from-main bytes (on-disk hash moved and the added-paragraph grep counted 0, so the mutation is proven landed, not hoped for), and check:api-surface-declarations exited 1 naming contracts.txt. Restore was git checkout HEAD -- against an absolute REPO_ROOT, hash equal afterwards, git status --porcelain empty.
⇒ this is a display cap, and the honest framing is: the aggregate's list is a sample. The defect is that nothing in the output says so.
Why it is worth fixing anyway
The audience is not hypothetical. ⭐ The domain:spec seat dispatched three merge-and-regenerate rounds in one shift against the same new artifact family, and each one reads this aggregate's shard list first. A cap that silently drops shards is read by exactly the round that most needs the full set.
Remedy candidates (⛔ verify before taking either)
Cheapest and probably sufficient: when the captured output is truncated, say so — e.g. print … and N more line(s); run <the standalone gate> for the full list. The cap stays, the misreading stops.
Raise or remove the cap for this gate family specifically. ⚠️ Weigh it: the cap presumably exists because a shard diff can be enormous, and an aggregate that dumps thousands of lines is its own defect.
⭐ Pin whichever is taken with a case where the captured output exceeds the cap, and assert on the "N more" notice or on the full list. A fix verified only against output that fits under the cap tests nothing.
Four-facet reading
Who is hurt — the next agent running a merge-and-regenerate round, who reads three shard names and believes that is all of them.
What the rule should be — output that is truncated says it was truncated; ⛔ a sample may not be presented in the shape of a complete list.
Cost of the honest fix — one line plus a pinned case; no behaviour change, no published surface, no changeset.
What was built instead — a display cap with no marker, which is indistinguishable from a short complete list.
Scope: packages/spec/scripts/check-generated.ts and its tests. ⛔ No published surface, ⛔ no runtime file.
Closed under the landed queue charter — ⛔ not a judgment that this finding is wrong, 2026-09-21T05:49Z
PR #19462 merged as 733f42d62f — 「the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight」 (ruling #202 B). Three of its lines decide this card, read off origin/main, ⛔ not recalled:
⇒ all three conditions hold, so the charter closes it. ⛔ This seat is not overruling the finding, and ⛔ not saying the measurement behind it is wrong — the readings on this card stand as written and are the reason it can be re-opened cheaply.
How it comes back
Either of the two the charter names, and ⛔ nothing else is needed:
the first line gains Unblocks: #N naming an open product card this gate is actually blocking, or
it names the published surface it protects — a face a user or a published package can read.
⚠️ A gate defect that only makes an instrument noisier, or only costs a seat a re-measurement, is exactly what this charter declines to spend a dev on. The maintainer's ruling behind it, verbatim: 「我只是不希望开发时间不停的话在仪器上,创业阶段dev应该集中做业务功能」.
⛔ This comment records a state change; it is not a ruling and it grades nothing.
Activity
os-steve commentedon Sep 21, 2026
Closed under the landed queue charter — ⛔ not a judgment that this finding is wrong, 2026-09-21T05:49Z
PR #19462 merged as
733f42d62f— 「the dev queue is product-only — tooling cards close at first grading, broken gates are deleted, ≤1 tooling dev in flight」 (ruling #202 B). Three of its lines decide this card, read offorigin/main, ⛔ not recalled:SKILL.md:343pm:queue= 有具名落点或复现的具体缺陷,无可问之事;⛔ 工具/门禁修复不由此进。SKILL.md:175toolingrowtooling卡同样关。Applied to this card, measured at this act:
toolingUnblocks: #N?⇒ all three conditions hold, so the charter closes it. ⛔ This seat is not overruling the finding, and ⛔ not saying the measurement behind it is wrong — the readings on this card stand as written and are the reason it can be re-opened cheaply.
How it comes back
Either of the two the charter names, and ⛔ nothing else is needed:
Unblocks: #Nnaming an open product card this gate is actually blocking, or⛔ This comment records a state change; it is not a ruling and it grades nothing.
Generated by Claude Code