Repository navigation
fix(components): page:tabs probes related counts from the named record, not the loaded row (objectui#13010 part 1) - #13019
Merged
objectstack-fleet[bot] merged 4 commits intoOct 19, 2026
Conversation
A held-transport harness that mounts the real record page over the real adapter on a HotCRM-shaped authored page (tab strip with related lists, reference rail aside) and logs every request with the wave it went out in. It pins what holds today: the record read, both explain questions (update and delete, two different bodies) and the rail's top=3 card reads go out in wave 1. The tab strip's top=1 badge probes follow in wave 2, keyed on the record body's id; their fix lives outside this part's file surface. Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB Co-authored-by: Claude <noreply@anthropic.com>
…d, not the loaded row (objectui#13010) The tab strip keyed its badge probes on ctx.data.id, so every probe waited for the record read and went out a wave behind it. It now reads ctx.recordId, the required member every RecordContextProvider fills (the route's id on a record page). A list behind a node-level visibleWhen, or in a tab whose item-level visibleWhen decides it, keeps waiting for the record body, since its gate reads it. Pins: page-tabs-probe-route-id-13010 (ungated list probes before the row lands, gated ones after, no record named no probe) and the record-open harness (13 requests in one wave; a badge whose declared filter differs from its card still probes with its own filter). Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB Co-authored-by: Claude <noreply@anthropic.com>
… true while the row is absent (objectui#13010) Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB Co-authored-by: Claude <noreply@anthropic.com>
…t; declare app-shell in the changeset (objectui#13010) Claude-Session: https://claude.ai/code/session_01XVp19E1MYUTFM3dnkwz8gB Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
objectstack-fleet
Bot
deleted the
claude/issue-13010-record-open-waves
branch
October 19, 2026 03:50
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 #13010
Clause-②: no
Part 1 of the card, Wanted items 1–2, under the seat rulings in comment 6258704497. Item 3 is dropped because its premise was disproved. Items 4 and 5 stay on the card.
What changed
page:tabs(packages/components/src/renderers/layout/containers.tsx) now keys its related-count badge probes onctx.recordId, the record the context names (the route's id on a record page). It used to key them onctx.data.id, the id inside the loaded row, so every probe waited for the record read and went out a wave behind it.recordIdis a required member ofRecordContextValueand every provider fills it, so this is a single read, not a fallback. A list whose visibility the record decides keeps that wait: one behind a node-levelvisibleWhen, or in a tab whose item-levelvisibleWhendecides it, is probed once the row has landed, as before.RelatedCountStore.fetch. It cannot register first without a timing hack. After item 2, the tab strip's probe effect runs in the first commit and reachesRelatedCountStore.fetchafter a single microtask hop (itsgetObjectSchemaawait). The rail's read is gated by itsIntersectionObservervisibility latch, which flips after a frame, and only then does it start its own schema await. So the probe is always on the wire first; the after-table below shows thetop=1probes issued ahead of thetop=3reads. Making the rail win would mean dropping its visibility gate (which keeps ahidden xl:flexrail from querying at all) and relying on effect order plus microtask order. Each badge probe now shares wave 1 with its card's read, so the extra wave is gone; the three count requests remain.security/explainPOSTs on a record open have different bodies,operation: updateandoperation: delete, fromplugin-detail'suseRecordEditable. objectui#11699's in-flight sharing is in the card's pin. The harness pins the two bodies.Wave table: the rendered harness, before and after
RecordDetailView.recordOpenWaves-13010.test.tsxmounts the realRecordDetailViewover the realObjectStackAdapterunder StrictMode, on a HotCRM-shaped authored page: a tab strip whose Related tab holds 3 related lists, the third with a declared status filter, plus a reference rail aside with 3 entries at limit 3. A held transport answers one wave at a time.d0934b919d)355c0146f3)In the card's in-app measurement the probes were wave 3 (at 1858 ms, after the record landed at 1.81 s). That wave is the one this removes.
Pins
packages/components/src/__tests__/page-tabs-probe-route-id-13010.test.tsx:recordId;visibleWhenwaits for the row;visibleWhenreads true while the row is absent waits for it;not_equals), and the card's read carries none;top=1probe where the card's read answered) is NOT here; see item 1 above.Ablations
Each was run once through
scripts/ablation-replace.mjs, which checks the anchor counts. Each restore was proven by blob hash:09c621807d6aequals HEAD, andgit diff HEADis empty.parentIdonctx?.data?.id: 3 tests red (the harness's wave-1 pin, and the ungated-list and node-gate pins).visibleWhenpin).visibleWhenpin). On its first run this ablation stayed green, because that pin's predicate (record.plan == 'pro') already reads false while the row is absent, so the line was untested. I rewrote the pin's predicate torecord.plan != 'free', which reads true while the row is absent, and on the rerun it went red.Verification (head
355c0146f3)--maxWorkers=1, under the shared lock: 32 files, 252 tests passed. The run covers thepage-tabs-*family (the objectui#12987visibleWhencount pins and the objectui#12992 scope builder included),related-count-store*,record-reference-rail*, theRecordDetailView.related*pins (objectui#8882, objectui#4664, objectui#5795, objectui#11733),childWriteRefreshesParent-12244,recordOpenRequests-*,accessibleNames-12625,authoredActivityThreading-12249,PagePreview,SchemaRenderer.visibleWhenRecordBinding, and the two new files.--filter '@object-ui/app-shell^...': exit 0.@object-ui/componentstype-check (src and tests): exit 0, re-run after the final edit.@object-ui/app-shelltype-check: exit 0.containers.tsxhas 94 warnings, the same as on base.check:spec-floorsexits 1 with no-artifact (it needs a whole-workspace build), so it is NOT MEASURED; the order notes it may exit 1 on main.@object-ui/componentsand@object-ui/app-shell, and repo-widepnpm lint.Acceptance notes
Generated by Claude Code