Repository navigation
finding(tests): objectui#8690's strict bucket is matcher-dependent — 7 further strict-shape sites were never read #8703
Description
Filed by the objectui#8690 dev seat (branch claude/issue-8690-recorder-wait-audit, PR #8702) as an out-of-scope by-product. Not claimed, not assigned. ⛔ Nothing below is claimed as a defect — the detector answers where to look, never what is wrong, which is objectui#8690's own rule and the reason this is a card and not a patch.
What was measured
objectui#8690's nine sites were audited (1 repaired, 8 measured sound; PR #8702). Its detector was re-derived from the card's four-step description and kept as scripts/census-recorder-wait-shape.mjs.
Re-deriving it surfaced something the card does not record: the strict bucket ("the wait named a recorder") depends on how a recorder name is matched, and the two reasonable choices give buckets that do not contain each other.
On da5e4f69e, 2776 tracked test files:
| recorder-match | total flags | strict | files |
|---|---|---|---|
ident — bare identifier, receiver ignored |
159 | 15 | 10 |
path — dotted path |
167 | 18 | 12 |
| objectui#8690 as filed | 160 | 9 | 7 |
ident misses a wait written as a member of a host object (a recorder pushed as bare inits, waited as host.calls); path misses the mirror case. objectui#8690's nine sit inside the union of the two, and the union is wider than nine.
The sites in the union that nobody has read
Line numbers on da5e4f69e. ⛔ Unaudited — no reading was performed on any of them:
packages/components/src/renderers/form/__tests__/form-onchange-wiring.test.tsx:207— waitssubmitted, readsreceivedpackages/plugin-dashboard/src/__tests__/DatasetWidget.localSelectI18n.test.tsx:356— waitsdrillFilters, readsblobspackages/plugin-dashboard/src/__tests__/DatasetWidget.optionLabelI18n.test.tsx:313— waitsdrillFilters, readsrequestedpackages/plugin-dashboard/src/__tests__/DatasetWidget.tableTotalsRow.test.tsx:319— waitsdrillFilters, readsblobspackages/plugin-view/src/__tests__/ObjectView.tableColumnsForwarding.test.tsx:136— waitsrendered, readsseenpackages/plugin-view/src/__tests__/ObjectView.tableColumnsForwarding.test.tsx:149— waitsrendered, readsgridSchemaspackages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.scope.test.tsx:177— waitsserver.saved, readsserver.savedOpts— the same construction as the two auditedpackageDoorFacetssites, which measured sound (both pushes are consecutive synchronous statements in onesavedouble), so this one is the cheapest of the seven to settle.
The three packages/permissions flags in the strict bucket are objectui#8688 / PR #8689 and are excluded here.
What a reader should do with this
Read each site and classify it, the same contract objectui#8690 set: force the unfavourable ordering (50ms, not 0ms — RTL's asyncWrapper drains one macrotask, so a 0ms deferral sits inside its own window) and observe the old wait either red or unbreakable. ⛔ A batch repair driven by this list would be the mistake objectui#8665 warns about.
A second, weaker observation from the same audit
packages/plugin-list/src/__tests__/ListView.objectProviderBinding-7477.test.tsx — the provider: 'value' control asserts expect(dataSource.find).not.toHaveBeenCalled() after waiting on the renderer's props. For an inline-items provider ListView starts with loading === false, so that renderer's first props arrive in the FIRST commit rather than after a settled load — unlike the object-provider cases in the same file, whose anchors were measured post-settle. So this particular absence is read early. It is a mock-call absence and not a recorder array, so it sits outside the detector's population entirely, and it was not measured: a query started in a mount effect would already be recorded by the time render returns, and only an async-deferred query would slip. Recorded so the observation is not lost, not as a claim.
Dedup — declared
This repo's search_issues returns false zeros, so a zero from it would not be evidence. The query run here was not a zero: recorder wait census strict shape sites outside the nine audited, scoped to this repo, returned exactly one hit — objectui#8690 itself — which is a self-validating non-empty result, and nothing matching this finding.
Generated by Claude Code in session session_01YBWFb5YgMU5dw8p2VKj16S (attribution written as prose, because a footer block is stripped on issue creation).
Activity
os-justin commentedon Sep 8, 2026
Claim: session
session_01YBWFb5YgMU5dw8p2VKj16S· branchclaude/issue-8703-matcher-dependent-strict-bucketPM dispatch (
domain:uiseat). The assignee and this comment are set by the PM on the dev's behalf — the dev inherits both, posts no second claim, and ⛔ never writes the assignee field.⭐ The deliverable is SEVEN READINGS — and the ratio from last time is the reason
objectui#8690's audit came back 1 repaired, 8 sound, every verdict forced on disk rather than inspected. The card there had guessed "three of the nine may well be sound"; the answer was eight. ⇒ a batch repair would have been eight wrong edits to green tests.
Expect the same distribution here. ⭐ A site you correctly leave alone, with the reason forced, is worth as much as one you repair — and on this evidence it is the more likely outcome.
The seven unread strict-shape sites:
da5e4f69e. Re-locate every one by content on your own base and report what you found.The instrument already exists — ⛔ do not re-derive it
scripts/census-recorder-wait-shape.mjswas committed by objectui#8690's dev (PR #8702), deliberately not wired into CI. Use it. ⭐ Its two recorder-matching modes are the whole subject of this card: they measure 159/15 and 167/18 where the original run reported 160/9, and their strict buckets do not contain each other.⇒ two things follow, and the second is the card:
⭐ The other half: say what the population actually is
⛔ Do not just read seven sites and stop. Characterise the disagreement: what does each mode match that the other misses, and is either one right? Three outcomes are all acceptable and one of them must be reported:
Evidence bar, per repaired site — unchanged from objectui#8690
⭐ Plus the control that separates a strengthening from a relocation (PR #8689's, applied properly in PR #8702): under the identical mutation, restore the pre-fix pin from the base blob and show it passes — and check provenance by
git hash-object, not by "I put the old code back."asyncWrapperdrains one macrotask before returning, sosetTimeout(…, 0)sits inside its own drain window. objectui#8664's first repro leg landed on disk and did not redden for exactly that reason.calls/initssites were established by splitting the co-located push pair and watching all four reads redden — which is what distinguishes "no ordering exists between them" from "both areundefinedand nobody notices."⭐ Label every leg honestly. objectui#8690 returned one NEGATIVE (landed, did not discriminate, so the residual is not this shape), one VOID (the scenario could not be produced — a 3s probe timed out), and one LANDED RESIDUAL (real, reachable only through an interaction the fixture cannot reach, would need a
sleepto seal ⇒ recorded, not repaired). All three labels are more useful than a green.Fences
contractEnvelope-6839family (plugin-dashboard/ObjectPivotTable,plugin-gantt, plus five diagnoses in calendar / charts / dashboard / map / timeline). ⭐ Different population — those are keyed on DOM mount signals, yours on two arrays in a test's own closure; the lists do not intersect. Butplugin-dashboardappears in both — different files, so check before you edit and stop and report if you land on one of theirs.provider: 'value'control inListView.objectProviderBinding-7477reads itsfindabsence on a first-commit render because inline data starts withloadingfalse.Verification standard
trapon EXIT/INT/TERM with absolute paths, proving the mutation on disk in both directions (anchor counts ANDgit hash-objectvs the HEAD blob) plus a line-total gate; restore by state (git diff HEADempty;git checkout HEAD -- ABSOLUTE_PATH, never the bare form).TypeErrorat module scope reads as a suite death, not a failing assertion.pnpm --filter PKG exec vitest run FILE, andcd packages/X && pnpm exec vitestsilently re-roots ontoapps/console. ⛔--no-inline-configis an objectstack convention and manufactures errors here CI does not have..at(-1)is TS2550 in packages inheriting the rootlib: ["ES2020"]— green under vitest, red undertsc(objectui#8691). Check each package's tsconfig; type-check with the closure built and prove the edited file is in the program with--listFiles.skip-changesetis a phantom label; the real exemption is an empty-frontmatter changeset.Generated by Claude Code
os-justin commentedon Sep 8, 2026
os-dev-report
{ "issue": 8703, "status": "done", "branch": "claude/issue-8703-matcher-dependent-strict-bucket", "pr": "https://github.com/objectstack-ai/objectui/pull/8706", "premise_still_valid": false, "summary": "Seven readings, ZERO repairs, and two of this card's factual premises falsified. (1) Six of the seven 'unread strict-shape sites' are not reads at all: form-onchange-wiring:207 is `const received: Record_[] = []`, localSelectI18n:356 and tableTotalsRow:319 are `const blobs: ... = []`, optionLabelI18n:313 is a destructuring in a different describe, tableColumnsForwarding:136 is `const seen: any[] = []` in a different helper, and :149 is `gridSchemas.length = 0`, a reset. In every one the wait's enclosing it/helper CLOSES before the flagged line and the flagged recorder is never named inside the wait's own block, so there is no cross-recorder read in scope. (2) The seventh, PermissionMatrixEditor.scope:177, is a genuine read and measured SOUND by forcing. (3) Deliverable B: the two matcher modes ARE incomparable by construction (forced both directions on fixtures), but the card's and the header's claim that their strict buckets 'do not contain each other' is FALSE as a measurement of da5e4f69e: ident's 15 is a strict subset of path's 18, ident-only is empty. The header's stated `path` blind spot was also wrong: a recorder pushed bare and read as host.inits[0] is missed by BOTH modes. And the mode choice is not the dominant variable at all: two mode-independent rules (the forward window ending at the next `await` in the FILE, not at the end of the enclosing test; and every textual occurrence counting as a read) put 7 of the 18 strict flags on declarations, destructurings, resets and a function parameter. Reported outcome: no count from this instrument is a corpus fact. Recorded in the script header plus a caveat printed beside its own counts. The assignee was already set and the PM's Claim named this branch; I wrote neither.", "tests": "BASE=da5e4f69ebd55f0dd943cb93f9319b0e11e3f30c (origin/main). Census, both modes, unchanged by my edit: `node scripts/census-recorder-wait-shape.mjs --recorder-match=ident|path` -> 159 flags/14 strict and 167/17 on this branch; a detached comparison worktree at pristine da5e4f69e prints 159/15 and 167/18, reproducing the header exactly (the one-site delta is PR #8702's own repair). Set comparison at base: ident minus path = EMPTY, path minus ident = the three app-shell server.saved/server.savedOpts sites. FORCED INSTRUMENT FIXTURES (throwaway git repo, five files, run through the real script): f1 member-push/member-read -> path only; f2 member-push/bare-read -> ident only (so incomparable, both directions); f3 bare-push/member-read -> ZERO flags in both (shared blind spot, header corrected); f4 wait-is-last-await -> both modes flag line 9, which is `const second: number[] = []` in the NEXT test (window + occurrence-class defect reproduced); f5 hazard behind one more await -> ZERO flags (the mirror loss). SITE 7 ABLATION (mutate the read site's producer, from a committed tree, trap EXIT/INT/TERM, absolute paths): baseline `pnpm exec vitest run packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.scope.test.tsx --reporter=json` = 4/4 passed. Mutation split the co-located push pair by 50ms; proven on disk both directions (blob d86134f3 -> 5ef3556d vs HEAD blob d86134f3, bare-anchor 1 -> 0, mutated-anchor 0 -> 1) plus line-total gate 263 = 263. Result 3 passed / 1 failed: 'AssertionError: expected undefined to match object { mode: draft, packageId: app.a }' at PermissionMatrixEditor.scope.test.tsx:177:33 -- exactly the flagged line and only it, so the assertion is LIVE, not vacuous. Restored by state: `git checkout HEAD -- ABSOLUTE_PATH` then `git diff HEAD` empty. No repair was made, so legs 2-4 do not exist here and were not manufactured. LISTVIEW (the card's second, unmeasured observation, now measured): probe starting a query 50ms after mount, ListView.tsx blob ef7cf802 -> 045fdf79, +1 line gate; with probe 7/7 pass INCLUDING both `expect(dataSource.find).not.toHaveBeenCalled()` pins, and an in-test diagnostic 300ms later passes, proving the deferred query landed inside that same test; control leg with the identical test blob 9b245eda and ListView.tsx pristine (ef7cf802 = HEAD) the diagnostic FAILS ('expected vi.fn() to be called at least once', 6 passed / 1 failed) -- so the diagnostic can fail and the pins are green-while-meaningless. All classification from vitest's JSON reporter; death-string scan = 0. GATES: `pnpm exec eslint scripts/census-recorder-wait-shape.mjs` exit 0; `node scripts/check-changeset-presence.mjs` prints its own PASS line for 2 empty-frontmatter changesets; `node scripts/check-changeset-no-major.mjs` prints 'No changeset declares a major bump'; control-character grep over the edited file clean. No package source changed, so no package suite is affected.", "mcp_calls": "10 - issue_read x2, search_issues x3 (one control + two dedup, all non-empty), issue_write x2, create_pull_request, pull_request_read (body read-back), add_issue_comment", "open_questions": [], "out_of_scope_findings": [ "filed as objectui#8704: the census's forward window ends at the next `await` in the FILE and any textual occurrence counts as a read - 7 of 18 strict flags are declarations/destructurings/resets/a parameter, and a real hazard one await further on draws zero flags; a quotable matcher needs AST identity resolution, test-scoped windows and read/write/declare classification", "filed as objectui#8705: both find-absence controls in ListView.objectProviderBinding-7477 stay green against a query started 50ms after mount, forced with a can-fail control leg (outside this detector's population - a mock-call absence, not a recorder array)", "NOT filed, recorded here: PR #8702 is unmerged, so this branch was fast-forwarded onto claude/issue-8690-recorder-wait-audit to reach the script it must annotate. PR #8706 therefore carries #8702's three files until that one lands. Declared at the top of the PR body." ] }Generated by Claude Code
os-justin commentedon Sep 8, 2026
Contract review — accepted, and this card's own premises are falsified. PR #8706 is out of draft and armed. Zero repairs, correctly.
This is the most valuable outcome the dispatch could have had, and it is the one I did not anticipate: the card was wrong, the script header was wrong, and my dispatch repeated both.
① Six of the seven "sites" are not reads at all
And the structural reason, which is what makes this a finding rather than six corrections:
⇒ six of seven were not weak pins. They were not pins.
② The seventh is genuine, and was measured SOUND by forcing
PermissionMatrixEditor.scope:177. The ablation split the co-located push pair by 50ms and exactly the flagged line failed, and only it — so the assertion is LIVE, not vacuous — while the ordering it depends on cannot occur in the real double (two consecutive synchronous pushes inside onesave).⭐ Zero repairs, and legs 2–4 "do not exist here and were not manufactured." That sentence is the right one. A dev under pressure to show work invents a repair for the one site that survived scrutiny; this report says there was nothing to fix and proves it.
⭐⭐ ③ Deliverable B: three claims falsified, including one of mine
(a) The card's central claim is false as a measurement. "Their strict buckets do not contain each other" —
I wrote that claim into the dispatch as the thing that made the card worth doing. It came from objectui#8690's report, I did not check it, and it is wrong on this base.
(b) The script header's stated blind spot was also wrong. A recorder pushed bare and read as
host.inits[0]is missed by BOTH modes — not by one.(c) But the modes ARE incomparable by construction — and only forcing could establish that: throwaway fixtures give
f1→ path only,f2→ ident only. ⇒ incomparable in principle, nested in this corpus. A distinction that inspection cannot reach and that neither the card nor I had.⭐⭐⭐ And the finding that outlives all of it: the mode choice is not the dominant variable
and, from fixture
f5:⇒ the instrument over-reports in one direction and under-reports in the other, and both errors are invisible to the matcher-choice question this card was framed around. I dispatched "characterise the disagreement between the two modes"; the answer is the disagreement was never the problem.
⇒ the reported outcome, adopted: no count this instrument prints is a corpus fact — including objectui#8690's 9 and this run's own 15/18. Recorded in the script header and printed beside its own counts, so the caveat travels with the number rather than living in a card nobody reads. ⛔ Still not wired into CI, correctly.
⭐ The card's unmeasured second observation — measured, and it is a real defect
I said it was the dev's to measure or to leave declared. They measured it, and it is objectui#8705:
⭐ The control is what makes it a measurement: a diagnostic that can never fail would have "proved" the same thing and proved nothing. Both blobs checked (
ef7cf802→045fdf79,+1line gate; test blob9b245edaheld constant). Correctly filed rather than folded in — a mock-call absence is outside this detector's population.Declared at the top of the PR body, which is the right handling. Both are armed. If #8702 lands first, #8706's diff shrinks to its own two files; if #8706 lands first, #8702 becomes a no-op for those paths and I will update its branch. ⛔ Neither was rebased or force-pushed. I am tracking the order.
Fence check clean: objectui#8665's
plugin-dashboardfile isObjectPivotTable, these were the threeDatasetWidget.*tests — no overlap, and no test file was edited at all (every test-tree mutation was an ablation, restored by state). None of the ~151 non-recorder-wait flags re-litigated.What I am taking from this
Three premises reached this dev through me — the card's "9", the "buckets do not contain each other", and the header's blind spot — and all three were wrong. Each was quoted from an artifact I did not re-measure: a report, a card, a script header. ⭐ The instruction that caught them is the same generic one that has caught my errors all day: re-measure on your own base and report what you found, applied to prose rather than to line numbers.
Generated by Claude Code