Repository navigation
Cross the four uncrossed scan surfaces #1834 measured and reported — the walk against the literal, and one ruling on whether a filename counts as content (epic #1579) #1839
Description
Activity
- addedpm:epicParent delegated to a dedicated epic PM — other PMs never dispatch into its subtreeParent delegated to a dedicated epic PM — other PMs never dispatch into its subtree
on Sep 9, 2026 Claim:session_01DuzfS5chho38Yx1jxx9DEj→ branchclaude/issue-1839-cross-uncrossed-surfacesDispatched by the epic PM for #1579. The dev inherits this claim — ⛔ do not post a second
Claim:, ⛔ do not touch the assignee field.Base off
mainat965933bor later. ⛔ Notclaude/issue-1581-lint-strict-flip.⭐ Read PR #1838's body first. It is your input, not background: the four surfaces in this card are its measured output, and its inventory table tells you which 28 to leave alone.
Model: Opus, per 「没有 fable 派 opus」.
Deliverable: a draft PR. 「等总监复审」 — ⛔ not ready-for-review, ⛔ no auto-merge, ⛔ no merge, however green CI is.⭐ A verdict of "not blind after all, repair reverted" is a correct and valued outcome on any of these four. That is precisely what happened on #1834 and it was the right result. ⛔ What is not acceptable is calling a surface blind without the two legs.
Generated by Claude Code
os-dev-report
{
"issue": 1839,
"status": "done",
"branch": "claude/issue-1839-cross-uncrossed-surfaces",
"pr": "#1840",
"premise_still_valid": true,
"summary": "Base 965933b (origin/main, no sibling branch in the tree). All four surfaces were blind and all four are repaired: six assertions across five files, every one inside an EXISTING self-test block — no newit, no new gate, no new file, no widened surface, suite unchanged at 3455 tests / 165 files. (1) docs-object-term-consistency: TEST_FILES must contain the ROW_LABEL ledger the neighbouring blocks read by literal path, the literal single-sourced across its three readers; plus the same cross derived from the row's own LEDGERS list, because the ablation showed the identical mutation also dropped test/automation-docs-coverage.test.ts while the shippedmissingcheck stayed green — pinning one exemplar left the same defect class open two rows down. (2) hook-query-predicate: the surface must still hold awhere:predicate,predicateKey()single-sourced so the rule and the surface check cannot discriminate different classes. (3) collaboration-capabilities: the *.object.ts sweep asserted nothing at all; the class is any member, so a count IS the content proof. (4) docs-drift and docs-conversion-rate-spelling: the carrier lists proved by existsSync / readFileSync must also be reached by the walk. RULING ASKED FOR BY THE CARD — a path in a walk's output IS a content pin exactly when the other half of the pair already pins that file's CONTENT; standing alone it pins a name. That single rule is why the same gesture is right in surfaces 1/4a/4b (ROW_LABEL, the verbatim CEL quote, and the carrier spelling are each pinned on a neighbouring line) and wrong in surface 2 (nothing anywhere pins _line-item-price-fill.ts's content). The PM's filename-proxy ruling therefore STANDS, and it is measured, not asserted: with every hook body relocated under src/objects/hooks/ and anexport *shim left at each old path, the surface still holds 44 real .ts files and still contains a file named _line-item-price-fill.ts, carries 0where:predicates, and the shipped assertion passes 71/71 with a plantedfilter:defect in the relocated body. EQUALITY IS NOT AUTHORABLE in hook-query-predicate: hook-write-shape.test.ts:444 can do it because CASES is a hand-authored roster its runtime half executes, giving the scanned call sites something to equal; hook-query-predicate's runtime half stands up a synthetic in-memory ObjectQL on crm_account to measure kernel where/filter behaviour, runs no hook body and enumerates no call site, and nothing else under test/ enumerates the query sites either. Manufacturing a second population means authoring a new hand-maintained roster of the 18where:carriers — a gate farm growing by exactly the mechanism AGENTS.md scope rule 3 forbids. So the honest weaker form was taken, as the card allowed. Changeset: empty frontmatter, per the PM's #1834 ruling and the #1778 precedent. PR #1840 is a DRAFT, no closing keyword (Part of #1839), auto-merge NOT enabled, not marked ready — 「等总监复审」.",
"tests": "ALL EXIT CODES CAPTURED BEFORE ANY PIPE. pnpm verify on final HEAD 568c25a, all eight green: validate 0 · typecheck 0 · lint 0 · lint:i18n-gate 0 · hygiene 0 · hygiene:tokens 0 · build 0 · test 0 (Test Files 165 passed (165),Tests 3454 passed | 1 skipped (3455)). TEST COUNT 3455 before / 3455 after — unchanged; test files 165 / 165.pnpm lint --jsonon this branch's own base 965933b vs final 568c25a: errors 0/0, warnings 13/13, suggestions 12/12 — NEITHER NUMBER MOVED. ABLATIONS — three legs per surface, same mutation at the same commit, only the assertion swapped; every mutation proved ON DISK (occurrence count before/after AND blob hash) before any result was read; every leg restored undertrap … EXIT INT TERMand proved BY BYTES (post-restore blob identical to HEAD,git diff HEAD --name-onlyempty,git status --porcelainempty). [1] TEST_FILES — defect 案件 planted in test/sharing-coverage.test.ts (1->2 occurrences, blob 5bba32bc..->8b193f05..); mutation: the walk gains&& !f.includes('coverage'), surface 165->157 real .test.ts files, ledger unreached, literal read still succeeding. CONTROL control-unmutated-surface-exit=1 (test/sharing-coverage.test.ts:1311: 案件). LEG A legA-old-assertion-exit=0, Tests 33 passed (33) — MISSED. LEG B legB-new-assertion-exit=1 at test/docs-object-term-consistency.test.ts:416:9, and after the derived cross was added, 3 failed | 30 passed with a second AssertionError at :557:9 naming BOTH test/sharing-coverage.test.ts and test/automation-docs-coverage.test.ts (leg A re-run on the extended assertion still exit 0, 33 passed). [2] hookFiles — defectconst ablationQuery = { filter: { id: 'lead_1' } };in the relocated lead.hook.ts (0->1, blob 0d92d1db..->a2a99a2a..); mutation: 18where:carriers moved to src/objects/hooks/ withexport *shims at the old paths — surface stays 44 files, keeps the name the old assertion reads, carries 0where:. CONTROL exit=1 (lead.hook.ts passes a filter: query key). LEG A exit=0, Tests 71 passed (71) — MISSED. LEG B exit=1 at test/hook-query-predicate.test.ts:346:7. [3] readdirSync(OBJECT_DIR) — defect inertenable: { feeds: true }in src/objects/account.object.ts (0->1, blob 2aa0c6fb..->16d0e994..); mutation: OBJECT_DIR swapped to a real, non-empty, class-free tree (src/flows, 26 .ts, 0 *.object.ts). CONTROL exit=1. LEG A exit=0, Tests 7 passed (7) — MISSED. LEG B exit=1 at test/collaboration-capabilities.test.ts:173:7.⚠️ NOT A MEASUREMENT, reported rather than read as a result: the first attempt at this one relocated the schemas into src/objects/schemas/ and came back legA-exit=1 withTests no testsandCannot find module './_picklists'— a LOAD failure, not an assertion, so it was NOT read as 'the surface was not blind'; the mutation was replaced with one that leaves the module graph intact and both legs re-run. [4a] docs-drift — defectAny deal over $100K routes through the large-deal path.appended to content/docs/sales/opportunities.mdx (0->1, blob cbb75df9..->c49e15e7..); mutation: walkDocs skips the sales directory, 201->171 pages reachable, all 30 sales pages still on disk and still passing existsSync. CONTROL exit=1 (content/docs/sales/opportunities.mdx: \"over $100K\"). LEG A exit=0, Tests 14 passed (14) — MISSED. LEG B exit=1 at test/docs-drift.test.ts:419:7. [4b] docs-conversion-rate-spelling — defect 转换率 appended to content/docs/analytics/cubes.zh-Hans.mdx; mutation: the walk skips analytics, 134->126 Chinese pages reachable, all four carrier files still on disk and still opened by readFileSync. CONTROL exit=1 (content/docs/analytics/cubes.zh-Hans.mdx:121 — 转换率). LEG A exit=0, Tests 4 passed (4) — MISSED. LEG B exit=1 at test/docs-conversion-rate-spelling.test.ts:131:9 (both carriers). No Leg A came back exit 1, so no repair was reverted. Control-byte self-scan over the five edited files and the changeset: no hits.",
"mcp_calls": "0 — every GitHub read and write went through the container's REST channel (repo-scoped probe green); no MCP GitHub tool was called",
"open_questions": [],
"out_of_scope_findings": []
}
Generated by Claude Code
Filed by the epic PM (
session_01DuzfS5chho38Yx1jxx9DEj), 2026-09-09.pm:epicreserves it for the epic PM.⭐ This card is not new analysis. It is #1834's own measured output, carried forward exactly as that card intended: it asked for "a measured inventory … here are the N and what each needs", delivered 34 surfaces measured, 28 already content-pinned, 1 repaired, 1 self-falsified, 4 reported. These are the 4. ⛔ Do not re-run the sweep — read #1834 and PR #1838 and act on what they already measured.
The shape, in one line
A guard walks a root and filters by suffix; a second mechanism in the same file names a specific carrier by literal path. If the walk stops reaching that carrier, nothing notices — the count is still healthy and the literal read still succeeds. #1778 crossed exactly this pair for
PACK_FILES; these four were left uncrossed.The four
TEST_FILESintest/docs-object-term-consistency.test.ts> 100only. TheROW_LABELcontent pin beside it reachestest/sharing-coverage.test.tsby literal path, not throughTEST_FILES.hook-query-predicate.test.ts> 10plustoContain('_line-item-price-fill.ts').collaboration-capabilities.test.tsfeeds: truesweep oversrc/objects/*.object.tsasserts nothing at all about its surface..object.ts, so a count is a content proof. ⭐ #1834 left this for "whoever owns the vacuity sweep"; #1770 is CLOSED, so nobody owns it. It is yours.docs-drift.test.tsanddocs-conversion-rate-spelling.test.tsVERBATIM_PAGES,CARRIERS) proved byexistsSyncon a literal path while the sweep runs over a walk.expect(PAGES).toContain(carrier)in each — or establish that the count plusexistsSyncalready is the pin, and say why. Exposure is low (both walks rooted atcontent/docs, counts> 100/> 50); ⛔ that is a reason to be honest about the verdict, not a reason to skip measuring it.⭐ The PM's ruling on #2, and you may overturn it with a measurement
toContain('_line-item-price-fill.ts')pins that the file list contains a name. It does not pin that any file in the surface issues a query. A file that is renamed, emptied, or stripped of itswhere:keys leaves that assertion green. ⇒ A filename proxy is not a content pin. 18 of 44 files carry awhere:key today, so the class is well populated and the honest form is available.The shape to reach for is row 5's — the equality cross-reference in
hook-write-shape.test.ts:444, which this seat re-read and confirmed:expect(covered, …).toBe(sites.length), the scanned surface'supdate(call sites against the writes the runtime half exercises. ⭐ That is the strongest form in this repo and it is the one that falsified #1834's dev when they thought that file was blind.hook-write-shapecan do equality because its runtime half enumerates the writes. Ifhook-query-predicatehas no such second population, equality is not authorable and the honest check is the weaker "the surface holds at least one instance of the class". If my ruling is wrong for this file, say so with the measurement — that is how the last three cards went, and each time the dev was right.⛔ How NOT to do it
it, no new gate. PR test(scan-surfaces): content-level sweep of the test farm, and pin the ctx-shape surface to its call sites #1838 changed one file and left the suite at 3455 tests, unchanged. ⭐ Match that.content/docs/releases/, and no governed surface.hook-write-shape.test.ts— Content-level sweep of the test farm's scan surfaces: which guards prove only that their surface is NON-EMPTY, rather than that it CONTAINS the thing the rule is about? (epic #1579) #1834 established it is already the strongest pin here and reverted its own repair to it.⭐ Acceptance — the same two legs, per surface you change
For every guard you touch: two legs against the same mutation at the same commit, only the assertion swapped.
trap … EXIT INT TERM; prove the restore by bytes (post-restore blob identical toHEAD,git diff HEAD --name-onlyempty,git status --porcelainempty).toBeGreaterThan/toHaveLengthmisses equality-form content pins three blocks away. Before you call any of these four blind, read the whole file.Also:⚠️ neither number should move; say so if one does) · test count before and after, expected unchanged.
pnpm verifygreen, exit codes before any pipe ·pnpm lint --jsonbefore/after on your own base (Changeset
Empty frontmatter. ⭐ Ruled by the PM on #1834, correcting the dispatch wording that card carried:
.github/workflows/changeset-check.yml:33states in its own comment that "An empty-frontmatter changeset still counts: it is the sanctioned" declaration that a PR releases nothing, and #1778 — this whole line of work's precedent — used exactly that for the same kind of change. ⛔ Do not name a package bump fortest/**-only work; it would accrete a CHANGELOG row for something no user can see.Base and coordination
mainat965933bor later. ⛔ Notclaude/issue-1581-lint-strict-flip.claude/issue-1826-field-consumers-six(feat(metadata): give four declared-but-unnamed fields the consumer they should already have #1831) ·claude/issue-1827-contact-mailing-address(feat(contacts): give the contact form its mailing-address block #1837) ·claude/issue-1834-content-level-sweep(test(scan-surfaces): content-level sweep of the test farm, and pin the ctx-shape surface to its call sites #1838). ⭐ test(scan-surfaces): content-level sweep of the test farm, and pin the ctx-shape surface to its call sites #1838 is the one that matters to you — it touchestest/hook-input-shape.test.ts, which is not one of your four, so there is no file collision; but its inventory is your input, so read PR test(scan-surfaces): content-level sweep of the test farm, and pin the ctx-shape surface to its call sites #1838's body before you start. ⛔ Do not measure against a tree containing any of the three.⛔ Not in this card
hook-write-shape.test.tsspecifically.--strictflip (Turn onos lint --strictin this repo's verify chain and prove the gate reds (epic #1579, step 2b — the half that needs a release) #1581) ·field-no-consumers(Give the six declared-but-unnamed fields the consumer they should already have — clear 6 of the 12field-no-consumerswarnings blocking #1581 (epic #1579) #1826 / The fivecrm_contact.mailing_*fields: the CSV importer writes them and the authored contact form may show none of them — clear the last 5field-no-consumerswarnings blocking #1581 (epic #1579) #1827) · the family cards Retire the local tests that re-implement the platform's flow / predicate / readonly-write lint rules, onceos lint --strictguards them (epic #1579, step 3, family F1) #1582–Retire the local hook / action / flow write-shape tests the platform's *-body-write-* and flow-node-write rules already enforce (epic #1579, step 3, family F6) #1587.src/**change — if a repair needs one, that is a finding to report, not a rider.Refs: #1579 (epic) · #1834 / PR #1838 (where these four were measured — read them, do not re-derive) · #1778 (the precedent, and file #1 belongs to it) · #1770 (closed — which is why surface #3 is unowned) · #1755 · #1529.