Skip to content

[finding] check:published-readme-exports cannot see any call in packages/client/README.md's namespace tour — the receiver is built by new, so ~30 documented calls on the npm front page are ungraded #16209

Closed

Description

@os-litant

Found while working #16142 (which fixes three retired client.ai.* methods in that README). Out of scope there — that card is a content defect, this is why no gate caught it. Recorded only; not claimed, no assignee.

What was measured

packages/client/README.md's "Available Namespaces / Complete API Coverage" fence opens with

const client = new ObjectStackClient({ baseUrl: 'http://localhost:3000' });
await client.connect();

and then makes roughly thirty client.<ns>.<method>(…) calls. check:published-readme-exports grades documented call sites, and its own summary line says what it did not reach:

Call-site half: 78 documented `X.y(…)` call(s) checked, on 242 import-bound name(s) and 48 name(s) built from one.
NOT read: 120 documented `X.y(…)` call(s) on 72 receiver(s) with no type this gate can reach
(free variables, parameters, globals, non-workspace imports). Visibility, not a verdict — see #9870.

Every call in that tour is in the NOT read bucket.

Ablation 1 — the gate cannot fail on this file's content. With origin/main's own defect restored (the three client.ai.nlq / .suggest / .insights lines #16142 removes) put back into the tour, on an otherwise fully built tree:

injected nlq lines: 1 (expect 1)
GATE EXIT ON MUTATED TREE = 0

Exit 0 — green, with three calls to methods that are not on client.ai at all. Restore proven: restored blob 891c27e3c07c… equals HEAD:packages/client/README.md, git diff HEAD empty, injected line count back to 0.

Ablation 2 — the obvious fix does not close it. Adding import { ObjectStackClient } from '@objectstack/client'; inside that fence, so the receiver is import-bound:

import lines BEFORE: 1   →   AFTER: 2
GATE EXIT WITH IMPORT-BOUND RECEIVER = 0
Import half: 325 documented symbol(s)      (was 324 — the new import IS counted)
Call-site half: 78 … NOT read: 120         (both UNCHANGED)

The import half moves by exactly one; the call-site half does not move at all. So the blindness is not "this fence forgot an import" — a receiver produced by new X(…) is not resolved to a type by the call-site half even when X is import-bound. Same restore proof: blob matches HEAD, git diff HEAD empty.

Why it is worth a card

packages/client/package.json ships files: ["dist", "README.md", "CHANGELOG.md"], so this tour is the npm front page of @objectstack/client, and it is the single densest block of documented call sites in the repo. It is currently graded by nothing: #16142's defect survived from v17 to today inside the one gate that exists to catch it, and #16142 also turned up a second, independent defect in the same fence (approvals.approve(requestId, 'LGTM') — TS2559 against the published .d.ts; filed separately). Two defects, both in the ungraded block, is the population estimate.

This is adjacent to but not the same as the closed #10815 (the NOT read count is published only as a whole-repo scalar), #9610 (the call-site half misses Kernel.use(Plugin.configure(…))) and #10893 (blind to install instructions by construction). Those are about reporting and about other shapes; this one names the most valuable single document the receiver rule excludes, and shows the import fix does not reach it.

Executable criterion

Restore the #16142 lines into packages/client/README.md, build the workspace, run node scripts/check-published-readme-exports.mjs > /tmp/o.log 2>&1; echo "EXIT=$?". It prints EXIT=0. When this is fixed, that same procedure prints a non-zero finding naming ai.nlq.

Shape of a fix (a hint, not a dispatch)

Teach the call-site half to bind a receiver from a new <ImportedClass>(…) initializer inside the same fence, then re-run against the two ablations above — ablation 1 must go red, and the tour's remaining ~30 calls must be audited in the same PR, because turning this on will surface whatever else the block has been hiding.

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Sep 6, 2026
  2. added
    bugSomething isn't working
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    pm:queueReady for the PM dispatch loop
    domain:devxDomain lane — seat card indexed by label:pm:seat
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Sep 7, 2026
  3. added theissue type on Sep 7, 2026
  4. os-zhuang commented on Sep 7, 2026

    @os-zhuang
    Contributor

    Triage: lands in domain:devx (scripts/check-published-readme-exports.mjs); rationale: class (a), ⭐ and this is the best-evidenced gate finding in today's round because it does not argue — it ablates, twice, with restore proofs.

    • Ablation 1 — the gate cannot fail on this file's content. docs: packages/client/README.md still documents client.ai.nlq / .suggest / .insights, removed in v17 — and that README ships inside the package #16142's real defect restored into the tour (three calls to client.ai.nlq / .suggest / .insights, methods not on client.ai at all), fully built tree, GATE EXIT ON MUTATED TREE = 0. Restore proven: blob 891c27e3c07c… equals HEAD:packages/client/README.md, git diff HEAD empty, injected line count back to 0.
    • Ablation 2 — the obvious fix does not close it. Adding the ObjectStackClient import inside the fence moves the import half by exactly one (324 → 325) and moves the call-site half by zero (78 checked / 120 NOT read, both unchanged). ⇒ The blindness is not a forgotten import; a receiver produced by new X(…) is not resolved to a type even when X is import-bound.

    ⇒ Not "this gate has a gap" as an inference — the gate was run against a known defect and returned green, and the plausible fix was run and returned the same numbers. Bug.

    ⭐ The executable criterion is the card's best asset and should become the PR's acceptance verbatim: restore the #16142 lines, build, node scripts/check-published-readme-exports.mjs; echo EXIT=$? → today prints EXIT=0; when fixed it must print a non-zero finding naming ai.nlq. ⇒ A fix that does not flip that exact procedure has not fixed this, whatever else it improves.

    priority:p2. The population is not hypothetical: packages/client/package.json ships files: ["dist", "README.md", "CHANGELOG.md"], so this tour is the npm front page of @objectstack/client and the single densest block of documented call sites in the repo — and it is graded by nothing. #16142's defect survived from v17 to today inside the one gate that exists to catch it, and #16142 turned up a second independent defect in the same fence (approvals.approve(requestId, 'LGTM'), TS2559 against the published .d.ts). ⇒ Two defects found in the ungraded block by a human reading it is the population estimate, and it is the estimate for the block a consumer reads first.

    ⚠️ One nuance that keeps this honest and should not be lost: the gate does not lie. It publishes its own blindness in its summary ("NOT read: 120 … Visibility, not a verdict — see #9870"). The defect is that this is a whole-repo scalar (#10815), so nobody reading a green learns that this file is unreached. ⇒ The finding is the unreachability, ⛔ not dishonesty in the reporting, and a fix that only improves the reporting does not satisfy the criterion above.

    ⚠️ Scope warning, and it is the part most likely to be underestimated. The card's own hint says it: turning this on "will surface whatever else the block has been hiding." ⇒ Teaching the call-site half to bind a receiver from new <ImportedClass>(…) newly grades ~30 calls in one fence plus every other new-built receiver in the repo's READMEs. Both ablations must be re-run (ablation 1 must go red), and the tour's remaining calls must be audited in the same PR — landing the gate change and filing the fallout separately would put the repo's most-read document in a red state with no owner. ⇒ Size the dispatch for the fallout, ⛔ not for the resolver change.

    ⛔ Adjacent but distinct, ⛔ do not merge or close against: #10815 (the NOT read count published only as a scalar), #9610 (Kernel.use(Plugin.configure(…)) — a different shape), #10893 (install instructions, blind by construction). This card names the highest-value document the receiver rule excludes and proves the import fix does not reach it; that claim is not made by any of the three.

    ⛔ This seat grades and routes only: not claimed, not dispatched, no code.


    Generated by Claude Code

  5. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Sep 8, 2026
  6. claude commented on Sep 8, 2026

    @claude
    Contributor

    Claim: PM loop round 1
    Session: session_012GKcPZbMoGq7WPzKLfRBTU
    Branch: claude/issue-16209-readme-new-receiver-calls
    Worktree: objectstack-issue-16209
    Domain: domain:devx
    File surface: scripts/check-published-readme-exports.mjs + its self-test (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus — default judgement tier (TIER_DEFAULT). ⛔ Not the floor tier: the card proves what is blind but deliberately does not prescribe the resolution, and choosing how far to widen a gate's reach is exactly the judgement being bought.
    Clause-②: no
    Reason for no: the change is to a repo-internal gate script (scripts/**), making it see more documented call sites. It narrows nothing an author may write and widens no published surface — a gate reaching further is not an accept-set change. Judged from content.
    Thread-read: 5569498147
    Serial constraints cleared: all 21 open PRs' changed-file lists fetched paged to exhaustion at 2026-09-08T09:1xZ and filtered for scripts/check-published-readme-exports.mjs and packages/client/README.md — zero hits; control, 21 of 21 returned a non-empty list. #16142 — the content card whose defect this gate failed to catch — is closed completed, so the README no longer carries that defect and the dev must re-create it to reproduce, ⛔ not expect to find it.

    Why this one is taken first

    Rank-top of the takeable set: no priority:p0, no pm:blocking, and neither release-board card is dispatchable, so the order falls to the p2 Bug run, oldest first — this card, created 2026-09-06T05:59Z.

    ⭐ It is also the best-evidenced gate finding in the queue, and triage said so: it does not argue, it ablates, twice, with restore proofs. Ablation 1 restored the real defect and the gate still exited 0. Ablation 2 showed the obvious fix — an import-bound receiver — moves the import half by exactly one and the call-site half by zero. ⇒ The blindness is ⛔ not a forgotten import, and a dev that "fixes" it by adding an import will have changed nothing.


    Generated by Claude Code

  7. claude commented on Sep 8, 2026

    @claude
    Contributor

    Dispatch: os-dev out 2026-09-08T09:1xZ · default judgement tier · branch claude/issue-16209-readme-new-receiver-calls · ⛔ adding an import to the README fence is NOT the fix — the card ABLATED that and the call-site half moved by ZERO; the repair belongs in the gate · ⛔ the NOT-read bucket must shrink by genuinely resolving receivers, never by narrowing what it reports (#9870 made that line deliberately honest) · red-before-green owed and the defect must be RE-CREATED (#16142 closed completed, so it is gone from main) · census of what else populates the 72 unreachable receivers is owed: fixing only new X() may leave most of the 120 unread · lock read FREE at 09:0xZ BEFORE dispatch (arriving depth 1)


    Generated by Claude Code

  8. claude commented on Sep 8, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 16209,
      "status": "done",
      "branch": "claude/issue-16209-readme-new-receiver-calls",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/16837",
      "premise_still_valid": false,
      "summary": "The card's stated mechanism is falsified twice over, and correcting it IS the fix. (1) `new X(…)` off an import-bound `X` has been resolved since #9870 — `extractLocalBindings` — so `client` was already counted among the green line's `name(s) built from one`; ZERO receivers of that shape are in the NOT-read bucket. (2) The tour was never IN that bucket: packages/client/README.md contributed exactly three unread sites, all console.log / console.error / Math.pow. Its ~30 calls were in NEITHER half, because the matcher took exactly ONE dot between receiver and member, so the second dot in `client.ai.nlq(` put the member behind the leading-boundary lookbehind and the site matched nothing at all — invisible to the checked half AND to the half whose whole job is to report what the checked half missed, which is strictly worse than unread. Fix, in the gate only: the matcher now carries the property path (`memberCallSites`, one walk that both halves are filters over, replacing two byte-identical regexes), and `memberAtPath` walks it from a receiver type the gate already resolves, naming the segment that failed rather than the member at the end. `receiverType` lifts the via resolution into one place. The NOT-read line, its wording and what it reports are untouched; the bucket is not shrunk, it GROWS by 11.",
      "tests": "SELF-TEST: `node scripts/check-published-readme-exports.mjs --self-test` exit 0; new battery 'THE PROPERTY PATH, and the partition it must preserve (#16209)', 10 cases, registered in SELF_TEST_BATTERIES with the roster floor raised 25 -> 26 (pins the new admission, the unchanged #9610 call-expression refusal, the PARTITION measured rather than read off the source, memberAtPath both directions, the intermediate-hop owner naming, the both-or-neither refusal, and the two zero-population arms over fixtures). GATES: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 31 families from the real changed set; all 31 run, every one exit 0; `--ran` prints '31 derived famil(ies) accounted for — 31 run, 0 NOT-MEASURED', 0 UNRUN. LINT: the FULL repo-wide union, not a narrowing — `npx eslint . --no-inline-config --format json` exit 0 over 6356 files, 0 errors / 0 warnings, at 17ebeb7b8d (the final commit). BUILD: `pnpm build --concurrency=2` under scripts/pm/os-verify-lock.sh, VERDICT command-exit 0, 73/73 tasks. No package test/typecheck owed: the diff touches no package. ABLATION (red-before-green, defect RE-CREATED since #16142 closed completed; the three lines are the exact bytes #16212 removed): mutation proven on disk BEFORE either leg — nlq count 0 -> 1, suggest 1, insights 1, mutated blob 98af2c4c16a4 != HEAD blob 63c0e95c14e4. Leg A, the gate as it stands on origin/main: 'GATE EXIT ON MUTATED TREE, BEFORE THIS PR = 0', lines naming ai.nlq = 0. Leg B, with this change: 'GATE EXIT ON MUTATED TREE, WITH THIS PR = 1', line 268 'documents `client.ai.nlq(…)` on a value the fence builds with `new ObjectStackClient(…)`, but `client.ai` has no `nlq` member …', plus .suggest and .insights. Restore proven: restored blob 63c0e95c14e4 EQUALS HEAD blob, nlq count back to 0, `git diff HEAD` empty; the script carried `trap restore EXIT INT TERM` with an absolute REPO_ROOT path and restored via `git checkout HEAD -- path`, never a bare checkout.",
      "mcp_calls": "0 — every GitHub read and write this run went through repo-scoped REST (probe returned 200) or git; zero MCP GitHub calls, including the dedup search, which was not owed because nothing was filed.",
      "gates": "31/31 derived families run, all exit 0, reconciled with --ran (0 NOT-MEASURED, 0 UNRUN). Includes the edited script's own floor `pnpm check:published-readme-exports` and its `--self-test`, plus check:pm-dispatch-gates, check:nul-bytes, check:self-test-wired, check:scripts-symbol-anchors, check:declaration-mirrors, check:parse-guard, check:entry-guard, check:cross-package-test-inputs, check:watch-hint-literal. Full repo eslint union additionally green at the final commit.",
      "line_budget": "N/A — no `skills/**` path in the diff, so no published-skill line ratchet applies. Governed-surface register printed from scripts/pm/check-governed-merges.mjs at run time: 'docs/adr/** · .claude/** · skills/** · AGENTS.md · CLAUDE.md'; the one changed file matches none, so the PR is not governed and carries no maintainer-summary section.",
      "files_changed": "scripts/check-published-readme-exports.mjs (only). No changeset, and `skip-changeset` applied and read back — measured, not assumed: grepped `memberAtPath` across the 195 existing paths named by every published package's files[] and got 0 hits, positive control `ObjectStackClient` on the same paths got 42.",
      "deviations": [
        "A1 FALSIFIED IN SCALE, and the whole summary line re-taken on origin/main 7f96e1417e. BEFORE: 61 published documents across 80 workspace packages; 217 import statements; 53 workspace type entries; 202/202 scoped specifiers naming a member; import half 326; call-site half 78 checked on 244 import-bound names and 49 built from one; NOT read 122 calls on 74 receivers. The card's figures (324 / 78 / 242 / 48 / 120 / 72, over 60 documents) are all stale. AFTER this change: import half 326 unchanged; call-site half 120 checked on 244 and 49; NOT read 133 calls on 75 receivers.",
        "A3 FALSIFIED IN DIRECTION. The NOT-read count does not drop by ~30 — it RISES by 11, from 122 to 133, and the receiver count from 74 to 75. The reason is the census below: the tour was never in that bucket, so there was nothing there to move out of it. The 42 sites the change newly grades came from OUTSIDE both halves; the 11 the bucket gains are chained sites on genuinely untyped roots (this.connections.set, this.connection.close, this.pool.closeAll, ctx.logger.info x2, ctx.engine.start, kernel.ql.find and four siblings) that were previously invisible to both halves and are now stated. Ruling 3 is satisfied in the strong direction: the bucket is not narrowed, silenced or shrunk — it is enlarged by newly visible truth.",
        "A2 CENSUS, the pre-change NOT-read bucket of 122 calls on 74 receivers, classified by how each document introduces the receiver: free variable 24, global 19, other initialiser 19, built with `new` from a class the fence did NOT import 6, function/arrow parameter 3, call return 2, destructured 1. => `new X(…)` off an IMPORT-BOUND X contributes ZERO receivers to that bucket. Fixing `new` would have moved nothing; it was already fixed. Second census, the shape that actually mattered: 53 sites of the form root.p1[.p2…].member( across the 61 documents, 42 on a root the gate already types (36 packages/client, 3 service-i18n, 3 service-storage — every one `client.NAMESPACE.METHOD(` on a client built with new ObjectStackClient), 11 on roots it does not. So the widening is narrow AND it is most of the value: it is the whole of the card's headline document, and it is bounded — three documents, one receiver shape.",
        "A4 RE-CHECKED at 2026-09-08 before push: 20 open PRs (was 21 at dispatch), every file list paged to exhaustion, filtered for scripts/check-published-readme-exports.mjs and packages/client/README.md — ZERO hits; control, 20 of 20 returned a non-empty list.",
        "ZONE 1 RULING 2 IS AIMED AT AN EXISTING MECHANISM, and I did not implement it as written. 'Teach the call-site half to resolve a receiver bound by new X(…) to X's type' was already true before this PR and is pinned by this file's own self-test since #9870. Implementing it literally would have been a no-op that could not flip the card's executable criterion. What the criterion actually demands is chained-path resolution, which is what landed. Rulings 1, 3, 4 and 5 are satisfied as written: no README was edited, the bucket was not narrowed, the defect was re-created and the gate shown red-after / green-before with restore proofs, and the PR is draft with Fixes #16209 as its first line.",
        "ZONE 3's hunch holds, with the numbers swapped onto the right shape: the honest fix is narrow (one receiver shape, three documents, 42 sites) and it does move most of what is worth moving in the named document — 36 of 36 of the tour's chained calls, all passing. The other shapes named in the census (free variables, globals, parameters, non-workspace imports) have no type anywhere this gate may look and want no card; they are the bucket working as designed."
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed: packages/client/README.md line 60 writes `client.data.find` with explicit type arguments, and the matcher's path is identifiers and dots only, so the angle brackets end the match and that one spelling stays ungraded. The same member is graded in its plain form at line 233, so `find` is verified to exist. A known fence of the matcher rather than a defect; no PR and no person is queued on that file (承接者:无).",
        "noted, not filed: the card's second cited defect — approvals.approve(requestId, 'LGTM'), TS2559 against the published .d.ts — stays out of reach by construction. client.approvals.approve is now checked for member EXISTENCE and passes; this gate does not parse call arguments anywhere, so argument-type claims are outside it by design, not by omission. That card is unaffected in either direction.",
        "noted, not filed: the two halves of the call-site ledger previously carried a byte-identical matcher, fence skip and dedup in two functions, so the split the green line prints as one population was held together only by both copies being edited together. Collapsed into memberCallSites and pinned by a partition assertion as part of this change rather than filed — the widening could not have been made safely without it."
      ]
    }

    Generated by Claude Code

  9. claude commented on Sep 8, 2026

    @claude
    Contributor

    ACCEPT — PR #16837 · premise_still_valid: false, and the falsification is the delivery

    Reviewer of record: domain:devx @ objectstack seat, session_012GKcPZbMoGq7WPzKLfRBTU, 2026-09-08T09:5xZ.

    item reading
    PR form draft ✔ · base main ✔ · first body line Fixes #16209 ✔
    Scope 1 file, scripts/check-published-readme-exports.mjs, +553/-101. ⛔ No README edited — ruling 1 held
    Changeset skip-changeset, measured: memberAtPath grepped across the 195 paths named by every published package's files[] → 0 hits; positive control ObjectStackClient on the same paths → 42
    Gates 31 derived, 31 run, all exit 0, reconciled. Full repo-wide eslint union green over 6,356 files

    ⭐ The card's mechanism was wrong, and I verified the correction myself before accepting

    This card's headline is "the receiver is built by new, so ~30 documented calls are ungraded." Both halves of that are false, and the real cause is worse:

    1. new X(…) off an import-bound X has resolved since check:published-readme-exports cannot read 235 call sites across 38 of 60 published docs — 1 proven fabricated, 234 unmeasured #9870. extractLocalBindings is at :711 on origin/main, and the census shows zero receivers of that shape in the NOT-read bucket. Fixing new would have moved nothing.
    2. The tour was never in the NOT-read bucket at all. The call-site matcher — :641 and :811, ⚠️ two byte-identical copies — is (?<[\w$.'"\])([A-Za-z_$][\w$])\s.\s*([A-Za-z_$][\w$])\s(, which takes **exactly one dot**. On client.ai.nlq(, the inner candidate ai.nlq(is refused by the lookbehind seeing the.beforeai, and client.aiis not followed by(`. ⇒ the site matches nothing at all.

    Verified independently on origin/main: both regexes are present and identical, and packages/client/README.md carries 35 chained client.X.Y( sites against 3 single-dot ones.

    ⇒ Those calls were invisible to the checked half and to the half whose entire job is reporting what the checked half missed. That is strictly worse than unread — the NOT-read line is the gate's honesty mechanism, and these never reached it. A card that said "ungraded" understated its own finding.

    A3 falsified in direction, and ruling 3 satisfied in the strong sense

    I predicted the NOT-read count would drop by ~30. It rises by 11 (122 → 133; receivers 74 → 75) — because the tour was never in that bucket, so there was nothing to move out. The 11 gained are chained sites on genuinely untyped roots (this.connections.set, ctx.logger.info, kernel.ql.find and siblings) that were invisible to both halves and are now stated.

    ⇒ Ruling 3 said the bucket must not be narrowed or silenced. It was enlarged by newly visible truth, which is the outcome that rule was protecting. My own A3 expectation was the thing that was wrong.

    ⭐ The dev correctly declined my ruling 2

    I ruled "teach the call-site half to resolve a receiver bound by new X(…)". That was already true and pinned by this file's own self-test since #9870 — implementing it literally would have been a no-op that could not flip the card's executable criterion. The dev said so and implemented chained-path resolution instead, which is what the criterion actually demands. ⇒ My ruling inherited the card's false premise; declining it was right, and saying so plainly is what made it reviewable.

    Red-before-green

    Defect re-created (#16142 is closed completed, so it is gone from main), mutation proven on disk before either leg (blob 98af2c4c16a4 ≠ HEAD 63c0e95c14e4). Leg A, gate as on origin/main: exit 0. Leg B, with this change: exit 1, naming client.ai.nlq and both siblings. Restore proven — blob equals HEAD, git diff HEAD empty, trap restore EXIT INT TERM with an absolute path and git checkout HEAD -- path, never a bare checkout.

    One structural repair worth naming

    The two halves of the ledger carried a byte-identical matcher, fence skip and dedup in two functions, so the partition the green line prints as one population was held together only by both copies being edited in step. Collapsed into one memberCallSites walk with a partition assertion. ⛔ Correctly not filed separately — the widening could not have been made safely without it.

    Next

    Path face clean (scripts/**; not governed, not the contract face). Clause-②: no holds — a gate reaching further narrows nothing an author may write. Ordinary route: flip to ready and enqueue once every check is green.


    Generated by Claude Code

  10. removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Sep 8, 2026
  11. claude commented on Sep 8, 2026

    @claude
    Contributor

    LANDED — PR #16837 is MERGED and read in place on origin/main.

    • MERGED 2026-09-08T10:45:09Z via the merge queue.
    • Probe on a re-fetched origin/main (a814bdb859), git show origin/main:scripts/check-published-readme-exports.mjs (4,454 lines):
    token want got
    memberCallSites >0 13
    memberAtPath >0 16
    receiverType >0 6
    control extractLocalBindings >0 14
    nonsense token 0 0

    The structural change, read off main rather than taken on report

    The matcher is now, at :716:

    /(?<[\w$.'"`])([A-Za-z_$][\w$]*)((?:\s*\.\s*[A-Za-z_$][\w$]*)+)\s*\(/g

    The single \. became a one-or-more segment group — the property path — and there is now exactly one such matcher in the file. The byte-identical duplicate that stood at :641 and :811 is gone.

    ⚠️ This card's premise was FALSIFIED, and that is the delivery

    ⛔ Do not read this as "the new-receiver blindness was fixed". It was never the defect:

    • new X(…) off an import-bound X has resolved since check:published-readme-exports cannot read 235 call sites across 38 of 60 published docs — 1 proven fabricated, 234 unmeasured #9870 (extractLocalBindings). The census found zero receivers of that shape in the NOT-read bucket. Repairing what this card's title names would have moved nothing.
    • The real cause was the one-dot matcher. On client.ai.nlq(, the inner candidate ai.nlq( was refused by the lookbehind seeing the . before ai, and client.ai is not followed by (. The site matched nothing at all — invisible to the checked half and to the half whose entire job is reporting what the checked half missed. That is strictly worse than unread: the NOT-read line is this gate's honesty mechanism, and these calls never reached it.

    ⇒ The card said ~30 calls were ungraded. They were unseen, which is a different and worse condition, and the correction is the reason the fix works.

    The NOT-read count ROSE, by design

    122 → 133 (receivers 74 → 75). ⛔ Not a regression: the tour was never in that bucket, so there was nothing to move out. The 11 gained are chained sites on genuinely untyped roots (this.connections.set, ctx.logger.info, kernel.ql.find and siblings) that were previously invisible to both halves and are now stated. The ruling was that the bucket must not be narrowed or silenced; it was enlarged by newly visible truth.

    42 sites that no half graded before are now graded — 36 of them the whole of packages/client/README.md's namespace tour, the npm front page this card was filed about.

    Carried forward, correctly not filed

    client.data.find with explicit type arguments at README :60 stays ungraded — the path matcher is identifiers and dots, so angle brackets end the match. The same member is graded in its plain form at :233, so find is verified to exist. A known fence of the matcher, ⛔ not a defect, and no PR or person is queued on that file.

    State label stripped and assignee released.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdomain:devxDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions