Repository navigation
test(scan-surfaces): cross the four uncrossed walk-vs-literal pairs #1834 reported - #1840
Merged
Merged
Conversation
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
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
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
…plar The surface-block cross names one ledger. The LEDGERS table beside it names three for crm_case, each read by literal path, and the other two were left uncrossed by exactly the mechanism this card is about: the same mutation that proved the surface blind also dropped automation-docs-coverage.test.ts from the walk, and the `missing` check stayed green because it reads by literal path too. One assertion, inside the same existing `it`, derived from the row's own ledger list so a new TERMS row is crossed for free. Part of #1839 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DuzfS5chho38Yx1jxx9DEj
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.
Part of #1839 (epic #1579). ⛔ No closing keyword: the epic PM closes the card after
triage, same as PR #1838. #1834, #1778, #1770, #1755 and #1529 are named below for
provenance only; none of them is addressed here.
What this card asked, and what the tree answered
Not a new sweep — #1834 already measured the farm and PR #1838 reported these four. The
question here is narrower: a guard walks a root and filters by suffix, while a second
mechanism in the same file names a specific carrier by literal path. Does anything tie
the two together? For all four, no. Repaired, five assertions in five files, each one
inside an existing self-test block.
Measured against
965933b—origin/main, no sibling branch in the tree.TEST_FILES(docs-object-term-consistency)hookFiles(hook-query-predicate)readdirSync(OBJECT_DIR)(collaboration-capabilities)PAGES/VERBATIM_PAGES(docs-drift)pages/CARRIERS(docs-conversion-rate-spelling)⭐ The ruling the card asked for: when does a filename count as content?
The card asks whether
toContain('_line-item-price-fill.ts')is a content pin, and thefour surfaces only stop contradicting each other under one rule, which is the answer:
That is why the same gesture is right in three files and wrong in the fourth:
docs-object-term-consistency— the neighbouring blocks assert whattest/sharing-coverage.test.tsmust still say (ROW_LABEL, the Simplified label,the Traditional cell). Only reachability was missing, so
toContain(ledger)completesthe pair.
docs-drift—VERBATIM_PAGES' content is pinned by the block below (each page mustquote the compiled CEL condition). Same.
docs-conversion-rate-spelling—CARRIERS' content is pinned on the very next line.Same.
hook-query-predicate— nothing anywhere pins_line-item-price-fill.ts's content.So there the name is load-bearing for nothing, and the honest repair is a pin on the
class itself.
The PM's ruling stands, and it is not a matter of taste — leg A measured it. With
every hook body relocated under
src/objects/hooks/and anexport *shim left at eachold path, the surface still holds 44 real
.tsfiles and still contains a file named_line-item-price-fill.ts, carries 0where:predicates, and the shipped assertionpasses: 71 passed, with a planted
filter:defect sitting in the relocated body.⭐ Is the equality form authorable in
hook-query-predicate? No — measured.The card asked for this to be measured before copying
hook-write-shape.test.ts:444, andthe measurement says do not copy it.
hook-write-shapecan writeexpect(covered, …).toBe(sites.length)because it has asecond population: its
CASEStable is a hand-authored roster of every derived write,and its runtime half executes each one, so the scanned call sites have something to be
equal to.
hook-query-predicatehas no such population. Its runtime half stands up an in-memoryObjectQLon a syntheticcrm_accountand asserts kernel behaviour forwhere/filter— it never runs a hook body and enumerates no call site. Nothing else in
test/enumeratesthe query sites either. Manufacturing one would mean authoring a new hand-maintained roster
of all 18
where:carriers — a new ledger to keep in step, which is a gate farm growing byexactly the mechanism AGENTS.md scope rule 3 forbids, to buy a stronger pin on a rule whose
own class is well populated.
So the honest form is the weaker one the card names — the surface holds at least one
instance of the class — and
predicateKey()is single-sourced so the rule and the surfacecheck cannot come to discriminate different classes. Today: 44 files, 18 carrying a
where:predicate.The five repairs
docs-object-term-consistency.test.tsexpect(TEST_FILES).toContain(ROW_LABEL_LEDGER)in has pages and ledgers to scan; the literal single-sourced across its three readersdocs-object-term-consistency.test.tsLEDGERSlist, in the ledgers that pin a row for this object still carry one — see belowhook-query-predicate.test.tswhere:carrier, in finds files to checkcollaboration-capabilities.test.tsschemaFiles.length > 10, hoisted out of theforhead in no*.object.tsrestatesfeeds: truedocs-drift.test.tsVERBATIM_PAGES⊆PAGES, in reads the real published pages…docs-conversion-rate-spelling.test.tsexpect(pages).toContain(file)in the existingit.each(CARRIERS)The ablations — three legs each, exit codes captured before any pipe
Every mutation proved on disk (occurrence count before/after and blob hash) before
any result was read; a no-op would have been refused and the run re-done. Every leg
restored under
trap … EXIT INT TERMand proved by bytes: post-restore blob identicalto
HEAD,git diff HEAD --name-onlyempty,git status --porcelainempty.CONTROL = defect present, surface unmutated, shipped guard → must fail (the defect is
real). LEG A = same defect, surface mutated, old assertion → must pass (blind).
LEG B = same defect, same mutation, new assertion → must fail.
1 ·
TEST_FILES— the walk vs. the ROW_LABEL ledgerDefect:
案件, a retiredcrm_casespelling, planted intest/sharing-coverage.test.ts(1 → 2 occurrences, blob
5bba32bc…→8b193f05…). Mutation: the walk gains&& !f.includes('coverage')— surface 165 → 157 real.test.tsfiles, ledger nolonger reached, literal read still succeeding.
⭐ One addition beyond the card's literal wording, and the measurement that asked for
it. The card specifies "one line: the walk's output must contain that ledger file",
singular. But the
LEDGERStable names three ledgers forcrm_case, each read byliteral path, and leg B above shows the same mutation dropped a second one —
test/automation-docs-coverage.test.ts— out of the walk while the shippedmissingcheck stayed green, because it also reads by literal path. Pinning one exemplar leaves
the same defect class open two rows down in the same block, so the cross is also derived
from the row's own list, where a new
TERMSrow gets it for free. Re-measured on theextended assertion, same defect and same mutation:
2 ·
hookFiles— the walk vs. the filenameDefect:
const ablationQuery = { filter: { id: 'lead_1' } };— the #1229 defect — plantedin the relocated
lead.hook.ts(0 → 1, blob0d92d1db…→a2a99a2a…). Mutation: the 18where:carriers moved tosrc/objects/hooks/withexport *shims left behind, so thesurface stays 44 files and keeps the name the old assertion reads, while carrying
0
where:predicates.3 ·
readdirSync(OBJECT_DIR)— the surface that asserted nothingDefect: an inert
enable: { feeds: true }planted insrc/objects/account.object.ts(0 → 1, blob
2aa0c6fb…→16d0e994…). Mutation:OBJECT_DIRswapped to a real,non-empty, class-free tree —
src/flows, 26 real.tsfiles, 0*.object.ts.legA-old-assertion-exit=1withTests no tests—Cannot find module './_picklists'.That is a load failure, not an assertion, so it is not a measurement and was not read
as "the surface was not blind"; the mutation was replaced with one that leaves the module
graph intact and the legs re-run.
4a ·
docs-drift— the walk vs.VERBATIM_PAGESDefect:
Any deal over $100K routes through the large-deal path.appended tocontent/docs/sales/opportunities.mdx(0 → 1, blobcbb75df9…→c49e15e7…) — theexclusive phrasing #1087 exists to reject. Mutation:
walkDocsskips thesalesdirectory — 201 → 171 pages reachable, all 30 sales pages still on disk and still
passing
existsSync.4b ·
docs-conversion-rate-spelling— the walk vs.CARRIERSDefect:
本页的转换率口径与报表一致。appended tocontent/docs/analytics/cubes.zh-Hans.mdx— the rejected spelling. Mutation: the walkskips
analytics— 134 → 126 Chinese pages reachable, all four carrier files still ondisk and still opened by
readFileSync.Gates —
pnpm verify, every exit code read before any pipeEach step run in the foreground, redirected to a file,
$?read before any pipe. Alleight on final HEAD
568c25a, after the changeset commit.validate·typecheck·lint·lint:i18n-gatehygiene·hygiene:tokens·buildtest—Test Files 165 passed (165),Tests 3454 passed | 1 skipped (3455)Test count: 3455 before, 3455 after — unchanged. Test files: 165 → 165. No new
it,no new gate, no new file under
test/, matching PR #1838. Nothing to justify againstscope rule 3, because nothing was added.
pnpm lint --json, before on this branch's own base965933band after on568c25a:Neither number moved, as the card predicted.
Scope
Five files under
test/, plus a changeset. Six assertions, all inside existing blocks. Nosrc/**change — none of the fiverepairs needed one, and every ablation's
src/andcontent/mutation was restored andproved by bytes.
content/docs/releases/untouched. No governed surface. No surfacewidened.
hook-write-shape.test.tsuntouched, and the 28 surfaces #1834 found alreadypinned were not re-opened. The
--strictflip (#1581),field-no-consumers(#1826 /#1827) and the family cards #1582–#1587 are out of scope and untouched.
The changeset carries empty frontmatter — the sanctioned "releases nothing"
declaration
.github/workflows/changeset-check.yml:33documents in its own comment, andthe form #1778 used for the same kind of work, per the PM's ruling on #1834.
维护者速读(草稿)
改了什么 —— 四个守卫都是「走查一棵树 + 在同一文件里用字面路径点名某个承载
文件」,两者之间没有任何断言把它们扣在一起。走查一旦够不到那个承载文件,两个读数都
还是健康的:计数由另外一百多个文件撑着,字面读取照样打得开文件 —— 于是规则在一棵
真实、非空、却已经不含它要判的东西的树上继续报绿。#1778 给
PACK_FILES交叉过的正是这一对,这四个当时留着没交叉。五处修复,五个文件,每一条都放进已存在的自检块:
没有新
it、没有新门禁,测试数 3455 → 3455 一个没涨。⭐ 第一个面比派发词字面多了一条:LEGDERS表给crm_case点了三个账本,消融里同一个变异也把test/automation-docs-coverage.test.ts挤出了走查,而按字面路径读的missing照样绿 ——只钉一个样本,同一个缺陷类在同一个块里还开着两行,所以那条交叉改成从该行自己的账本
列表推导。
本卡要的那个裁决 —— 「文件名算不算内容?」答案是一条规则,四个面在它下面才不
互相矛盾:走查输出里的一个路径,当且仅当这一对的另一半已经钉住了那个文件的内容
时,才算内容钉子;单独站着,它钉的只是一个名字。 所以同一个手势在三个文件里是对
的(旁边的块已经钉了该文件必须说什么),在
hook-query-predicate里是错的 ——仓库里没有任何地方钉
_line-item-price-fill.ts的内容。PM 的裁决成立,而且是量出来的 —— 把 17 个 hook 体搬到
src/objects/hooks/并在原路径留下
export *壳,扫描面仍是 44 个真实.ts、仍含那个文件名、where:谓词归零,而出厂断言照样全绿(71 passed),同时一个
filter:缺陷就躺在搬走的 body 里。hook-write-shape能写等式,是因为它有第二个总体:
CASES是手写的派生写入名册,运行半边逐条执行,扫描到的调用点才有东西可等。
hook-query-predicate没有:它的运行半边是在合成的crm_account上立一个内存引擎量 kernel 行为,一个 hook body 都不跑,也不枚举任何调用点;
test/里别处也没有。硬造一个,就是新增一份要手工维护的名册 —— 那正是AGENTS.md 范围规则 3 说的门禁农场。所以取本卡点名的较弱形态,并把
predicateKey()单一来源化,规则和面检查不会漂成两个类。
风险与代价(含回滚) —— 风险低:只动
test/**五个文件,src/一个字节没动,不向用户发布任何东西。回滚 = revert 这两个 commit。
录」,回来是
legA-exit=1但Tests no tests,报Cannot find module './_picklists'。那是加载失败不是断言失败,不是一次测量,所以我没把它读成「这个面不瞎」,换了一
个不破坏模块图的变异重跑。
你要做的 —— 三件。① 复核那条「文件名何时算内容」的裁决,它是本 PR 的核心产出,
也是四个面处置不一致的唯一理由。② 确认 changeset 的空 frontmatter(门禁注释 + #1778
先例 + 你在 #1834 上的裁定)。③ 本 PR 停在 draft 等你复审 —— 「等总监复审」。
🤖 Generated with Claude Code
https://claude.ai/code/session_01DuzfS5chho38Yx1jxx9DEj
Generated by Claude Code