Repository navigation
test(i18n): point the #802 term guard's pack rule at the real zh-CN tree - #1778
Merged
Merged
Conversation
`PACK_FILE` named `src/translations/zh-CN.ts`, which was the whole zh-CN pack when the rule was written. The #1311 locale split moved every string out of it into `src/translations/zh-CN/`, leaving a 77-line barrel of re-exports, and the rule kept scanning the barrel — a file that cannot contain a label. It could no longer fire, and it did not: #1529's defect was re-injected verbatim into the live pack and the suite still reported 33 passed. The surface is now derived the way the three that survived that split are — walk a root, filter by suffix — so `_shared.ts` (real pack strings, reached only through the family files) is covered and the next module added under `zh-CN/` needs no edit here. The non-vacuity assertion in `the ledger and the scan surface are real` is extended to the pack: the files scanned must carry the label the other rules resolve through the stack. A file count could not have caught this, because the barrel is still one real file; that cross-check reads 0 on the old surface. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PpRjGNnwyo2J1rrmekxB1W
Test-only change; empty frontmatter is the sanctioned "releases nothing" declaration that .github/workflows/changeset-check.yml documents. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PpRjGNnwyo2J1rrmekxB1W
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
huangyiirene
marked this pull request as ready for review
September 8, 2026 10:40
os-steve
pushed a commit
that referenced
this pull request
Sep 9, 2026
`test/hook-input-shape.test.ts` rules A and B walk every `.ts` under `test/` and key on one token — a hook handler being INVOKED, `handler(`. The file already guards its detector with planted probes, but nothing in it claimed the scanned tree still holds a call site for that detector to read. Measured on this branch's base 965933b: 175 real `.ts` files in the surface, of which 31 call a handler directly and 13 already reach a hook through `runHookBody(...)` instead — a form neither rule matches. The class these rules discriminate within is migrating out of the surface while the surface stays 175 real files, so a file count could not report it. That is #1755's shape one tree over: a real member that cannot carry the thing keeps the rule green. Strengthened in place, inside the existing self-test block — no new `it`, no new gate, the file stays at 16 tests (#1778's shape). The invocation pattern is single-sourced as `CALLS_HANDLER` so rule B and the surface check cannot come to discriminate different classes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DuzfS5chho38Yx1jxx9DEj
os-steve
added a commit
that referenced
this pull request
Sep 9, 2026
Each of these four guards walks a root and filters by suffix, while a second mechanism in the same file names a specific carrier by literal path. Nothing tied the two together: a walk that stopped reaching the carrier leaves the count healthy and the literal read succeeding, so the rule reports clean over a real, non-empty tree that no longer holds what it judges. #1778 crossed exactly this pair for PACK_FILES. - docs-object-term-consistency: TEST_FILES must contain the ROW_LABEL ledger the neighbouring blocks read by literal path (literal single-sourced). - hook-query-predicate: the surface must still hold a `where:` predicate — the class the rule judges — not merely a filename. Equality against a second population is not authorable here: the runtime half queries a synthetic engine and enumerates no call sites. - collaboration-capabilities: the *.object.ts sweep asserted nothing about its surface; the class is any member, so a count is the content proof. - docs-drift / docs-conversion-rate-spelling: the carrier lists proved by existsSync / readFileSync must also be reached by the walk. All five assertions go into existing self-test blocks: no new `it`, no new gate, no new file, no widened surface. Part of #1839 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DuzfS5chho38Yx1jxx9DEj
os-steve
added a commit
that referenced
this pull request
Sep 9, 2026
Empty frontmatter — the sanctioned "this PR releases nothing" declaration documented in .github/workflows/changeset-check.yml, and the form #1778 used for the same kind of test-only work. Part of #1839 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DuzfS5chho38Yx1jxx9DEj
10 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1755
What broke, and which half of it
test/docs-object-term-consistency.test.tsreaches the Chinese language pack bytwo different mechanisms, and only one of them was broken.
%s is one Chinese word everywhere (#837)label derivation:297packFor('zh-CN'):252/:406offenders([PACK_FILE], …)PACK_FILEnamedsrc/translations/zh-CN.ts, which was the whole zh-CN packwhen the rule was written. The #1311 locale split moved every string out of it
into
src/translations/zh-CN/, leaving a 77-line barrel ofimport/re-exportrows. The rule kept scanning the barrel — a file that cannot contain a label —
so it could not fire.
Re-measured on this branch's base
2e0f4dd1, inheriting no number from the card:src/translations/zh-CN.tsline countcrm_caseterm in the barrelcrm_quoteterm in the barrelsrc/translations/zh-CN/**The ablation — a green run is not the evidence
The card's whole value is that the guard re-passed #1529's defect. So the
proof is two legs against the same mutation at the same commit, not a green
run. #1529's defect was re-injected verbatim into the live pack
(
src/translations/zh-CN/objects.commerce.ts,crm_quote.crm_contact.help),proved on disk before any result was read (retired-spelling count 0 → 1; blob
5e4e25b4…→cc96697a…), and the surface swapped underneath it:Restored under a
trap … EXIT INT TERMand proved by bytes, not by an exitcode: post-restore blob
5e4e25b4d8da439c0c8fb1c99436814ed2c83cc3, identical toHEAD;git diff HEAD --name-onlyempty.Why a directory walk, and not the barrel's imports
Both shapes were on the table; this one was chosen on a measurement. The barrel
imports seven modules — and
src/translations/zh-CN/_shared.tsis not oneof them. It holds real pack strings and is reached only through three family
files, so resolving the barrel's direct imports would have left a genuine
string carrier outside the surface, and a transitive resolver can go quiet the
same way the literal did when a specifier stops resolving.
The walk is instead the shape used by the three surfaces that survived the
#1311 split untouched —
HANS_PAGES,HANT_PAGES,TEST_FILESall walk a rootand filter by suffix. Re-derived against the tree as the card asks: those three
are healthy (67 / 67 / 164 files), and
packFor('zh-CN')resolves the mergedpack correctly.
PACK_FILEwas the only hardcoded literal path in that block,and the only one that drifted.
Self-extension is proved, not asserted — a new module dropped under
zh-CN/with no edit to the guard:
The one line beyond the path swap
The existing
the ledger and the scan surface are realcheck already proves theother three surfaces are non-empty. The pack surface is now proved there too —
in the same block, in the same shape, no new
it, no new gate (the suite isstill 33 tests). A file count would not have caught this bug, because the
barrel is still one real file, so the check is a cross-reference between the two
mechanisms instead: the files being scanned must carry the label the working
rule resolves through the stack.
That is the reading that was missing for the whole life of the bug: on the old
surface it is 0.
Gates —
pnpm verify, exit code captured before any pipeEvery step run in the foreground, redirected to a file,
$?read before anypipe. All eight on final HEAD
d9e6e5a:validate·typecheck·lint·lint:i18n-gatehygiene·hygiene:tokens·buildtest—Test Files 164 passed (164),Tests 3438 passed | 1 skippedhygiene,hygiene:tokensandtestwere re-run ond9e6e5aafter thechangeset commit, because
.changeset/is inside their scan surfaces.line_budget: NOT APPLICABLE, on the gate's own printed line rather than anassertion:
test/**is not insrc/**, so it is outside the ratchet entirely — thereading is unchanged at
authored total ~136,794 tokens.Scope
Exactly one file of behaviour:
test/docs-object-term-consistency.test.ts, plusa changeset. No translation file edited, no gate added,
content/docs/releases/untouched, and the
:297packForpath is not modified. The repaired rule isgreen on
main's content — no retired spelling is live in the pack today.No closing keyword is placed near #1530, #802, #1529, #1311 or #1598; none of
them closes here. #1530 remains open and is
pm:blockedon this card's closure.… the figure moved under the card". It did not move. Both numbers are the
same tree read two ways: 56 matching lines, 65 occurrences. Verified
identical at
a02d4c14(the PM's own measurement point) and at2e0f4dd, sothe two readings never disagreed about anything. The discipline the
assumption prescribes — inherit no number, re-derive — is what surfaced this;
only its stated cause was wrong.
rule at the real tree does not red it: the repaired rule is green.
维护者速读(草稿)
改了什么 —— 只改一个测试文件里一条规则的取包路径。
#802术语守卫里有两条规则,一条经 stack 解析、一直在正常拦截缺陷(⛔ 本 PR 不碰);另一条直接读
src/translations/zh-CN.ts这一个路径。#1311拆分把文案全搬进src/translations/zh-CN/之后,那个路径只剩 77 行的 re-export barrel,规则从此扫一个不可能含标签的文件。现在改成走目录(与该文件里三个没坏的扫描面同一形态)。
为什么改 —— 它是静默失效,不是报错失效:套件照样报 33 passed,而
#1529的缺陷原样注回真实语言包后仍然全绿。空转的守卫读起来就是覆盖率,这是最坏的失败方向。本 PR 用同一处变异、同一个 commit、只换扫描面跑了两腿:旧面 exit 0
放行,新面 exit 1 并点名到文件与行号。
风险与代价(含回滚) —— 风险低:改动只在
test/**,不发布任何东西给用户,src/一个字节没动。扫描面变大意味着以后真有退役词进语言包会红 —— 那正是它该做的事。今天不会红:
main的语言包里没有活的退役词。回滚 = revert 这两个 commit,守卫回到空转状态,无其它连带影响。
席位意见 —— (留空)
你要做的 —— 确认一处越界:除了换路径,本 PR 在已存在的
the ledger and the scan surface are real检查里加了一条断言(不是新it、不是新门禁,测试数仍是 33),要求被扫的文件必须含有另一条规则经 stack 解析出的标签。
理由是:光换路径不会阻止下一次目录搬迁重新武装同一个陷阱,而文件数量判据抓
不到本次缺陷(barrel 仍是一个真实文件)。若认为这超出本卡范围,删掉它即可,换路
径本身完整独立。
🤖 Generated with Claude Code
https://claude.ai/code/session_01PpRjGNnwyo2J1rrmekxB1W
Generated by Claude Code