Repository navigation
feat: scale task channel delivery (NEXUS-3721) - #1574
Conversation
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, integrating Rocket, Mantis and Groot.
Reviewed head da26d30c8a9f50a555e03a1e42804ec24a7d85b2 against base 5b2fdd6999f93fec0c06f8d9f021f05523c85951.
One correctness finding is inline. Separately, [P2] remove the internal tracker link from the public PR description: the “Bigger picture” section publishes an internal workspace URL, issue identifier and issue-title slug. Replace it with a public-safe requirement summary or public issue reference; keep internal coordination links in the private tracker. This is a public-material finding, not a credential-leak claim. No image attachments were present in the reviewed description.
Optional documentation cleanup: docs/channels.md:1110–1114 still describes the old 1,024-entry discovery caps and three-page scan bound; docs/relay-queries.md:967–968 still describes the old 1,024-ID/450 KB broker-interest limits. Align those passages with the new byte budgets.
Source-only review: no PR code, tests, app or native workflow executed. A single hosted-check snapshot showed CI required and reported test jobs successful; Windows native validation and browser flake checks were skipped. This does not establish live performance, runtime focus/accessibility, deployed relay limits or human acceptance. The linked private issue could not be read (403), so its requirements remain unverified. This COMMENT is not an approval or merge authorization.
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, integrating Rocket, Mantis and Groot.
Reviewed head b6f0aafc9a78f2584a73bd1d0408fc8b255b8f0d against base 7fb1c417184be55e1bb3285ddb9e8585218a286c. Follow-up scope: prior findings and changes introduced by the fixes/main merge.
One new P2 merge-interaction finding is inline. The earlier replay → finite read → live alert-loss finding is addressed in source, with regression cases for that ordering and finite-first history. The public-description finding in the prior review remains unresolved; no attached images were present. Prior optional stale-limit documentation cleanup also remains optional.
Source-only: no PR code, tests, apps or native workflows executed. A single hosted-check snapshot still had one WebKit browser shard running; Windows native validation and browser flake checks were skipped. Live performance, runtime focus/accessibility and human acceptance remain unverified. The linked private requirements issue returned 403. This COMMENT is not approval or merge authorization.
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, integrating Rocket, Mantis and Groot.
Reviewed head bf3825a6aa76d3bd31c778b03df52f4c9c532b17 against base 7fb1c417184be55e1bb3285ddb9e8585218a286c. Follow-up scope: the three-file watermark repair since b6f0aafc9a78f2584a73bd1d0408fc8b255b8f0d, prior findings, and regressions introduced by this fix.
No new actionable code findings. The previous stale-preview finding is addressed in source: resume() now applies the same rejected-version ordering as accept(), preserving denial for stale public metadata while allowing newer public recovery. Added unit and session-level regression cases cover both outcomes; they were inspected, not executed.
The public-description finding in the original review remains unresolved. No image attachments were present. The earlier optional stale-limit documentation cleanup remains optional.
Source-only: no PR code, tests, apps or native workflows executed. A single hosted-check snapshot showed JavaScript, Rust and browser jobs still running; Windows native validation and browser flake checks were skipped. Runtime focus/retry presentation, accessibility, live performance and human/native acceptance remain unverified. The linked private requirements issue returned 403. This COMMENT is not approval or merge authorization.
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, integrating Rocket, Mantis and Groot.
Reviewed head 690f416c3952af2ce4f07c3932a994ae4e02d2e5 against base 7fb1c417184be55e1bb3285ddb9e8585218a286c. Follow-up scope: the two-file creation-proof retention fix since bf3825a6aa76d3bd31c778b03df52f4c9c532b17, prior findings, and regressions introduced by this fix.
No new actionable code findings. Completed proof-read batches now survive unrelated access revocation; incomplete or revoked entries are removed, and identity guards prevent an older read from clearing a newer replacement. Strong resolution still bypasses background deduplication. The added lifecycle case covers completed-batch retention, pending-read abortion/retry and rejoin; it was inspected, not executed.
The public-description finding in the original review remains unresolved. No image attachments were present. Earlier optional documentation cleanup remains optional.
Source-only: no PR code, tests, apps or native workflows executed; CI was not assessed in this cycle. Runtime focus/retry presentation, accessibility, live performance and human/native acceptance remain unverified. The linked private requirements issue returned 403. This COMMENT is not approval or merge authorization.
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, integrating Rocket, Mantis and Groot.
Reviewed head 670e6050e2a57a5e1b3c7bec3c7dede65acef462 against base 336e8a147dedf12034301ccaa57d471f119dd906. Follow-up scope: integration since reviewed head 690f416c3952af2ce4f07c3932a994ae4e02d2e5; the 12 feature patches remain unchanged.
No new actionable findings in the reviewed integration. The merge retains the scale/replay cases and upstream policy-close tests; the prior replay-receipt and preview-watermark repairs remain present.
Source-only: no tests, app launches, or native relay workflows were run for this review. A one-time check snapshot reports CI required successful at the reviewed head; Windows validation was skipped. This does not establish native-scale performance, notification delivery, keyboard/assistive-technology behavior, or human acceptance. The PR’s older-head native measurements retain their original scope.
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, integrating Rocket, Mantis and Groot.
Reviewed head 77748a8994bba3823b88b50928463d9d347cbb83 against base 42c2433abe840aced12a06952d9e7df35e920e6f. Follow-up scope: public-directory merge integration since reviewed head 670e6050e2a57a5e1b3c7bec3c7dede65acef462; all 12 feature patches remain unchanged.
No new actionable findings. The merge preserves byte-based search reservation while admitting saved-directory candidates to provisional ranking. Exact resolution, cancellation, bounded reconciliation, and the earlier replay-receipt, rejected-metadata and proof-retention repairs remain intact in the inspected source. Search and emoji caller integration was also checked. The current public description contains no attached images.
Source-only: no PR code, tests, builds, app launches or native relay workflows were executed; CI was not assessed in this cycle. Runtime performance, keyboard/assistive-technology behavior and human acceptance remain unverified. The PR’s reported tests retain their stated revisions and limitations. This COMMENT is not approval or merge authorization.
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, integrating Rocket, Mantis and Groot.
Reviewed head 34a77c11a811196da4574059942cf9d438c3f520 against base 2346cffbd18f48b61bbe831c3933b1f1a95e0ae9. Follow-up scope: merge integration since reviewed head 77748a8994bba3823b88b50928463d9d347cbb83; all 12 feature patches remain unchanged.
No new actionable findings. Profile syncs share the existing wire budget and silence-probe reservation, and live-only batches retain the catch-up obligation after a planned renewal. The prior replay-receipt, preview-watermark and creation-proof-retention repairs remain present. The public description contains no attached images.
Source-only: no PR code, tests, builds, app launches or native relay workflows were executed; CI was not assessed. Runtime delivery, native-scale performance, keyboard/assistive-technology behavior and human acceptance remain unverified. The PR’s reported measurements retain their original revisions and limitations. This COMMENT is not approval or merge authorization.
|
🤖 Cross-PR alignment with guarded Nexus archive/restore (#2112; block/buzz#8909), reviewed at These changes are complementary and I found no overlap blocker to landing this PR first. This PR owns bounded channel delivery, replay, and discovery. Our work keeps ownership of fresh lifecycle authorization, family scope, stopping work before archive, and restoring without starting workers. The boundaries we will preserve during integration:
Synthetic merging #1507 + this PR is clean. Applying #2112 afterwards has one text conflict in This is a non-blocking integration note based on source and merge checks, not a combined runtime pass. |
Merge main and retain bounded channel batches with global continuity metadata. Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Merge main and preserve separate history routes during slow live refresh. Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, integrating Rocket, Mantis and Groot.
Reviewed head b4fd23b337d98d8b13782d670eec56bdad3d9ad3 against base fe4ddc9da7397dbbb6116115db35610821b21950. Follow-up scope: fixes and merge integration since reviewed head 34a77c11a811196da4574059942cf9d438c3f520.
[P2] Remove internal artifact links from the public PR description. The Testing section’s “native report” and “evidence” links expose internal infrastructure addresses and artifact identifiers. Replace these with a public-safe summary or sanitized public evidence; retain internal links in private coordination. This concerns the published URLs, not a claim that the linked contents are publicly accessible or contain credentials. No image attachments were present in the reviewed description; the internal artifact contents were not inspected.
No new actionable code defects established in the reviewed follow-up. The grant-triggered renewal and fallback preserve the bounded replay queue, while global continuity metadata reaches the session recovery owners. The earlier replay-receipt, preview-watermark and creation-proof-retention repairs remain present.
Optional documentation correction: docs/relay-queries.md:957 still says the 60-second timer renews established joined batches. It now checks the 15-minute fallback; grants trigger renewal separately. The minute cadence still applies to recovery hints and eligible failed-renewal retries.
Source-only: no PR code, tests, builds, apps or native relay workflows executed; CI was not assessed. Runtime delivery, scale performance, focus/accessibility and human acceptance remain unverified. The PR’s reported tests retain their stated revisions and limitations. This COMMENT is not approval or merge authorization.
Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
|
🤖 removed the internal artifact URLs from the description. The public summary now gives the tested SHA, results, counts, and limits. e958e75ce also corrects the timer text: grants renew batches, and the minute tick checks the 15-minute repair interval |
Merge main and document the separate batch and roster repair intervals. Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account.
Reviewed head e958e75cecea74a587f5b448d5422de32f011972 against base fe4ddc9da7397dbbb6116115db35610821b21950.
No actionable findings in this follow-up. Since the previous review at b4fd23b337d98d8b13782d670eec56bdad3d9ad3, the only repository change is the timer paragraph in docs/relay-queries.md (+5/−3 lines); runtime sources and base are unchanged. The wording now correctly distinguishes grant-triggered batch renewal from the minute timer’s 15-minute fallback check. The previously reported internal artifact links have also been removed from the current public description; no image attachments are present.
This used the small-follow-up solo exception after the previous four-Guardian review; no new independent team pass is claimed. Source-only: no PR code, tests, builds, apps or native workflows executed, and CI was not assessed. Runtime delivery, performance, focus/accessibility and human acceptance remain unverified by this review. The PR’s reported measurements retain their stated revisions and limitations. This COMMENT is not approval or merge authorization.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, with independent Rocket, Mantis and Groot coverage.
Reviewed head 26774bde4b6935652e319b3d108c5f35c7d12e2f against base 91b10df25af686d95109192045010b4e2c22e8d9, focusing on integration since the previous reviewed head e958e75cecea74a587f5b448d5422de32f011972. No new actionable findings.
The incoming native signature-verification path preserves frontend hash checks, rejects failed signatures before admission, and rejects cancelled read results. The roster backstop composes with existing owed/failed-read recovery; grant-driven batch renewal remains separate. The resolved documentation describes both 15-minute intervals consistently. These are recovery thresholds, not convergence guarantees under throttling, suspension or failure. The public description has no image attachments and keeps older native measurements explicitly attributed to their tested revision.
Source-only: no PR code, tests, builds, apps or native workflows executed; CI was not assessed. Current-head native performance, recovery/focus behavior and human acceptance remain unverified. Unchanged feature code was not reopened without new evidence. This COMMENT is not approval or merge authorization.
gilgtm
left a comment
There was a problem hiding this comment.
🤖 Two correctness findings on the current PR head: the live request batch exceeds the documented per-REQ ID cap, and a queued state-delta removal can survive a channel re-add under backpressure.
A pending route replaces its queued removal before the status delta drains. Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Daniel Rouleau <drouleau@squareup.com>
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, with independent Rocket, Mantis and Groot coverage.
Reviewed head 60859cc5143612a833ce485a206b09439cd58e7f against base 91b10df25af686d95109192045010b4e2c22e8d9. Follow-up scope: the two-file broker fix since reviewed head 26774bde4b6935652e319b3d108c5f35c7d12e2f. No new actionable findings.
A re-added pending route now replaces its buffered removal before the status delta drains. This preserves the browser’s recreated status row at the current interest revision. Repeated snapshots, reset/close cleanup, bounded batches and existing retry behavior remain consistent in the inspected producer and consumer. The added regression controls setup and drain ordering and checks the replacement route plus revision; it simulates backpressure and captures host frames, rather than exercising mounted browser UI.
The public description contains no attached images and distinguishes older native measurements from this browser-only correction. Native source is unchanged by this follow-up.
Source-only: no PR code, tests, builds, apps or native workflows executed; CI was not assessed. Runtime backpressure, focus/accessibility, performance and human acceptance remain unverified by this review. This COMMENT is not approval or merge authorization.
Follow-up to the capacity-cliff review of 2026-10-29 12:02 UTC. The discovery eviction and Members dialog parts of that review were dropped in the rebase onto main: #1574 replaced discovery's 1,024-entry cap with a 256 MiB byte budget and pins the shortened-id fallback, and #2028 pages the dialog's name reads. Review: threads.ts `reactionsCapped` - Dropped it. A full 500-reaction page forced `limited: true`, which ThreadPanel and MediaReviewViewer show as "Thread history limit reached." even while older replies still load. The target still opens, its 500 reactions are a lower bound, and live reactions keep arriving. relay-queries.md no longer says the view is marked `limited`. Review: halving gaps (a) and (b) - Each part is accepted as it lands. A transient failure on part k retries from part k at the halved size instead of from author 0. Kept because the code is no larger than before (the result array and `.then` go away) and is safe: - retryRead runs attempts one at a time with the caller's signal, so two attempts never share the hoisted cursor. - A part that lands after an abort is dropped, as before. - A promotion still rejoins `batch.reading`. Deliberately not changed: - Warm-cache eviction. ByteLru evicts in insertion order and nothing touches an entry on use. A request that loads enough new names therefore evicts the viewer's own profile and on-screen names, and so does a long session once it has seen 1,024 profiles. This predates the branch at every request size. The fix is a use-based policy in ensure(), or reading only the rows that render, as a follow-up. - Halving is still unmeasured against a real 8 MiB response. Performance: - Profile batches that fit the read budget are unchanged: one accept per batch. A halved batch publishes once per part rather than once per batch, so earlier parts' names show one read sooner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
Follow-up covering the review of 2026-10-29 12:53 UTC. The discovery eviction, channel-link pin and Members dialog parts were dropped in the rebase onto main (#1574 replaced the 1,024-entry discovery cap with a 256 MiB byte budget; #2028 pages the dialog's name reads). Review: profile halving - Dropped. The 2 MiB profile cache keeps only about a quarter of an 8 MiB response, so the parts that landed evicted each other, and the case was never measured. Removed the hoisted cursor, the `ReadError` match and their two tests. The batch read is main's again. - Kept: the 1,024-id cap, the Community admin and `from:` search catches, and settling every batch before a failure is reported. - Docs: channels.md says a batch whose response exceeds the 8 MiB read budget (for example heavy legacy inline avatars) still loads no names, and that reading only rendered rows is a follow-up. Review: threads.ts loadMore guard - Reverted to `!snapshot.canLoadMore || snapshot.limited`. With `reactionsCapped` gone it is equivalent, and the thread diff is now only the separate reaction filter. Tombstone read over the request budget: fixed in code - The target's tombstone read sent every overlay id in one `#e` list. The reader rejects filters over 64 KiB (about 975 ids) before sending, so a target with more overlay ids failed to open. One target read can return 499 safety overlays plus 500 reactions, and `remote` can hold more. Carrying only this response's ids would still exceed the budget. It would also stop re-reading tombstones for overlays already in `remote`. So the read now goes in parts of 900 ids: a `for` loop and a slice in place of the `if`, with no new state. Each part keeps the 500-event fail-closed check. Up to 900 ids it is one request, as before. - Test: the full-reaction-page target test now also carries 480 edits (980 overlay ids). It asserts two tombstone requests of 900 and 80 ids covering every overlay, and the newest edit as the content. Before, the reader rejected the request locally and no tombstone query was sent. Performance: - No read is added anywhere that worked before. Tombstone parts only apply above 900 overlay ids, which used to fail. - Profile batches are back to one accept per batch. - thread-target.test.ts signs its 500 reactions and 480 edits once in beforeAll (about 1.45 s); before, 500 were signed inside the test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
Fixes the second P2 finding in kalvinnchau's review of PR #2114 (2026-11-02 03:58 UTC, comment 4438794444). The first (discovery preview eviction keeping restrictive metadata) was dropped in the rebase onto main: #1574 replaced the 1,024-entry discovery cap with a 256 MiB byte budget, so there is no preview eviction to fix. Review: useSearchMessages.ts from:name namesakes (1608c3e48) - Real, and a regression of this branch. `scoped` matched only loaded names. When it found one member, `resolve` treated that member as unique, and the relay profile search ran only when `scoped` was empty. With more than 1,024 members (names load for the lowest 1,024 keys) or a failed batch (now caught), a namesake among the unloaded members was missed, and the search silently read the loaded member's messages. On main both cases threw, so the user saw an error, not a wrong answer. - Fix: the member names are partial when `ensure` rejects or a member is neither in the snapshot nor in `unnamed()`. `unnamed()` records members the relay answered without a kind 0, so profile-less bots and viewers do not count. This test also catches main's existing case, where the 2 MiB profile cache evicts early names during the same `ensure`. When partial, a loaded match no longer settles it: the existing relay name search runs too. Beside a loaded member match, its results count only if they are channel members, and they are merged with `scoped` before `resolve`. Two matches open the existing author picker, which already merges loaded members with the relay search. A full page of 40 still counts as ambiguous. A healthy roster takes the old path unchanged. - Residuals: in a large channel, a name with 40 or more relay matches always opens the picker. The relay does not fold accents, so an accented namesake past the cap is still missed, as on the existing relay branch. Performance: - from:name with 1,024 or fewer members whose names all load: no added request. One `some` over the roster with two Set lookups per member. - Otherwise: one `searchProfiles` (limit 40) per debounced query, the same cost the empty-`scoped` path already paid. Membership is checked with `includes` for at most 40 candidates. Tests: - useSearchMessages.test.tsx, 1,100 members with one Alice key starting with `1` (named) and another starting with `f` (past the cap): - Namesakes on both sides: the far one is never requested, one profile search, `ambiguousAuthor`, no message read. Fails on the previous code, which resolves to the loaded Alice. - A named member and a namesake outside the channel: one search, resolves to the member. Fails on the previous code (no search), and fails if the member restriction is dropped (ambiguous). - Only the member past the cap is named: resolves to her after one search. This guard passes before and after, as it should: the fix must keep this path. - Small fully read roster with a profile-less member: no profile search. A control that passes before and after. It fails if partial detection ignores `unnamed()`. - "resolves from:name on a roster larger than the profile budget when some names fail": its mock now answers the `search` filter, because the failed batches send it to the relay search. - Summed time for useSearchMessages.test.tsx: 2.04 -> 3.09 s, 6 -> 10 tests, about 0.27 s per new test. Also run: tsc, lint, and the useSearchMessages suite (10 passed). Not exercised in the running app. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
Follow-up to the capacity-cliff review of 2026-10-29 12:02 UTC. The discovery eviction and Members dialog parts of that review were dropped in the rebase onto main: #1574 replaced discovery's 1,024-entry cap with a 256 MiB byte budget and pins the shortened-id fallback, and #2028 pages the dialog's name reads. Review: threads.ts `reactionsCapped` - Dropped it. A full 500-reaction page forced `limited: true`, which ThreadPanel and MediaReviewViewer show as "Thread history limit reached." even while older replies still load. The target still opens, its 500 reactions are a lower bound, and live reactions keep arriving. relay-queries.md no longer says the view is marked `limited`. Review: halving gaps (a) and (b) - Each part is accepted as it lands. A transient failure on part k retries from part k at the halved size instead of from author 0. Kept because the code is no larger than before (the result array and `.then` go away) and is safe: - retryRead runs attempts one at a time with the caller's signal, so two attempts never share the hoisted cursor. - A part that lands after an abort is dropped, as before. - A promotion still rejoins `batch.reading`. Deliberately not changed: - Warm-cache eviction. ByteLru evicts in insertion order and nothing touches an entry on use. A request that loads enough new names therefore evicts the viewer's own profile and on-screen names, and so does a long session once it has seen 1,024 profiles. This predates the branch at every request size. The fix is a use-based policy in ensure(), or reading only the rows that render, as a follow-up. - Halving is still unmeasured against a real 8 MiB response. Performance: - Profile batches that fit the read budget are unchanged: one accept per batch. A halved batch publishes once per part rather than once per batch, so earlier parts' names show one read sooner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
Follow-up covering the review of 2026-10-29 12:53 UTC. The discovery eviction, channel-link pin and Members dialog parts were dropped in the rebase onto main (#1574 replaced the 1,024-entry discovery cap with a 256 MiB byte budget; #2028 pages the dialog's name reads). Review: profile halving - Dropped. The 2 MiB profile cache keeps only about a quarter of an 8 MiB response, so the parts that landed evicted each other, and the case was never measured. Removed the hoisted cursor, the `ReadError` match and their two tests. The batch read is main's again. - Kept: the 1,024-id cap, the Community admin and `from:` search catches, and settling every batch before a failure is reported. - Docs: channels.md says a batch whose response exceeds the 8 MiB read budget (for example heavy legacy inline avatars) still loads no names, and that reading only rendered rows is a follow-up. Review: threads.ts loadMore guard - Reverted to `!snapshot.canLoadMore || snapshot.limited`. With `reactionsCapped` gone it is equivalent, and the thread diff is now only the separate reaction filter. Tombstone read over the request budget: fixed in code - The target's tombstone read sent every overlay id in one `#e` list. The reader rejects filters over 64 KiB (about 975 ids) before sending, so a target with more overlay ids failed to open. One target read can return 499 safety overlays plus 500 reactions, and `remote` can hold more. Carrying only this response's ids would still exceed the budget. It would also stop re-reading tombstones for overlays already in `remote`. So the read now goes in parts of 900 ids: a `for` loop and a slice in place of the `if`, with no new state. Each part keeps the 500-event fail-closed check. Up to 900 ids it is one request, as before. - Test: the full-reaction-page target test now also carries 480 edits (980 overlay ids). It asserts two tombstone requests of 900 and 80 ids covering every overlay, and the newest edit as the content. Before, the reader rejected the request locally and no tombstone query was sent. Performance: - No read is added anywhere that worked before. Tombstone parts only apply above 900 overlay ids, which used to fail. - Profile batches are back to one accept per batch. - thread-target.test.ts signs its 500 reactions and 480 edits once in beforeAll (about 1.45 s); before, 500 were signed inside the test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
Fixes the second P2 finding in kalvinnchau's review of PR #2114 (2026-11-02 03:58 UTC, comment 4438794444). The first (discovery preview eviction keeping restrictive metadata) was dropped in the rebase onto main: #1574 replaced the 1,024-entry discovery cap with a 256 MiB byte budget, so there is no preview eviction to fix. Review: useSearchMessages.ts from:name namesakes (1608c3e48) - Real, and a regression of this branch. `scoped` matched only loaded names. When it found one member, `resolve` treated that member as unique, and the relay profile search ran only when `scoped` was empty. With more than 1,024 members (names load for the lowest 1,024 keys) or a failed batch (now caught), a namesake among the unloaded members was missed, and the search silently read the loaded member's messages. On main both cases threw, so the user saw an error, not a wrong answer. - Fix: the member names are partial when `ensure` rejects or a member is neither in the snapshot nor in `unnamed()`. `unnamed()` records members the relay answered without a kind 0, so profile-less bots and viewers do not count. This test also catches main's existing case, where the 2 MiB profile cache evicts early names during the same `ensure`. When partial, a loaded match no longer settles it: the existing relay name search runs too. Beside a loaded member match, its results count only if they are channel members, and they are merged with `scoped` before `resolve`. Two matches open the existing author picker, which already merges loaded members with the relay search. A full page of 40 still counts as ambiguous. A healthy roster takes the old path unchanged. - Residuals: in a large channel, a name with 40 or more relay matches always opens the picker. The relay does not fold accents, so an accented namesake past the cap is still missed, as on the existing relay branch. Performance: - from:name with 1,024 or fewer members whose names all load: no added request. One `some` over the roster with two Set lookups per member. - Otherwise: one `searchProfiles` (limit 40) per debounced query, the same cost the empty-`scoped` path already paid. Membership is checked with `includes` for at most 40 candidates. Tests: - useSearchMessages.test.tsx, 1,100 members with one Alice key starting with `1` (named) and another starting with `f` (past the cap): - Namesakes on both sides: the far one is never requested, one profile search, `ambiguousAuthor`, no message read. Fails on the previous code, which resolves to the loaded Alice. - A named member and a namesake outside the channel: one search, resolves to the member. Fails on the previous code (no search), and fails if the member restriction is dropped (ambiguous). - Only the member past the cap is named: resolves to her after one search. This guard passes before and after, as it should: the fix must keep this path. - Small fully read roster with a profile-less member: no profile search. A control that passes before and after. It fails if partial detection ignores `unnamed()`. - "resolves from:name on a roster larger than the profile budget when some names fail": its mock now answers the `search` filter, because the failed batches send it to the relay search. - Summed time for useSearchMessages.test.tsx: 2.04 -> 3.09 s, 6 -> 10 tests, about 0.27 s per new test. Also run: tsc, lint, and the useSearchMessages suite (10 passed). Not exercised in the running app. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
Why
Each Nexus task has a home channel. Large task rosters need live delivery within the relay limits.
What
Use stable batches for joined channels and a separate recent-event queue. Preserve one incoming alert when replay arrives before a live copy, including when a finite read arrives between them.
How
Each live request names up to 2,048 joined channels. Replay uses at most 10 filters per request, with 500 events per channel. Four channel setup slots bound active work. Access revocation preserves completed creation-proof reads for channels that remain accessible. Channel streams, artifact and profile syncs, replacements, and the silence probe share the 1,024-wire budget.
There is no fixed roster count limit. Discovery retains up to 256 MiB of signed records. Broker interest records have a 64 MiB limit. Status and establishment frames carry at most 512 changes and obey backpressure. The startup cache keeps its 8 MiB limit.
Risk
This affects shared delivery and discovery in both hosts. Byte limits can leave coverage partial. Large rosters can require fresh discovery after restart. Finite reads own full history recovery.
Testing
Agent checks pass on b4fd23b3 in the native debug app on a disposable arm64 Mac Blox host. The app uses generated identities and an isolated HTTPS/WSS relay. The operator waives a separate human test because no UX change is intended. No human pass is claimed.
Sixteen native phases pass. Steps cover small and large renewal, 2,050-channel startup, both live batches, disconnect/replay, removal/rejoin, public/private lookup, grant replacement, and real timer repair. Both batches render messages. Signed artifacts reach the native projection. Replay → finite read → delayed live delivery produces one incoming receipt and one alert admission.
Measurements use the default 300 calls/minute quota. Startup takes 315.293 seconds and 1,168 native calls. It returns proofs for all 2,050 channels, with 10 successful repeats. Full disconnect recovery takes 163.629 seconds and 790 native calls. It returns 2,050 proofs with no repeat. Startup and disconnect completion require full proof coverage and zero pending work. These are measured costs on this test host.
The complete capture has 3,577 native API calls: 3,293 HTTP 200, 280 cancellation responses with status 499, and four HTTP 429. Counts include fixture attempts, gaps between phases, and timer activity. Separate helpers make 2,159 calls, all HTTP 200. All 24 finite membership-notice reads return HTTP 200. Seeding uses 20,000 calls/minute while native sockets are closed.
Global recovery decisions stay separate. Small continuous replay avoids repeated full reads for profiles, statuses, emoji, read-state, and reminders. The large membership replay reaches its 500-event cut and triggers full recovery for its owners. Profile reads remain quiet. Global kind-0 names survive channel access loss. A full cache clear rejects a late response from the old generation. The held-response check proves result rejection, not cancellation of an active native connection.
Signed grants replace the affected batch and preserve the old wire through EOSE. A pending grant causes one follow-up replacement. With grant notices held, real timer repair starts 902.918 seconds after the prior REQ. Fresh messages and artifacts arrive after repair. No target replacement occurs before 15 minutes. Final state has 2,050 joined channels and zero pending profile, HTTP, or observed codec operations.
Renewal and policy-close checks inject signals through the actual NativeSocket wrapper. Public-local WSS does not exercise FI headers, assertion expiry, or backend renewal scheduling. Verified kind-30382 profile sync is unavailable, so native checks do not establish its shared 32-entry bound or profile UI behavior. Native focus remains unproved. Artifact UI, file upload, OS banners, other operating systems, and 100,000 native channels remain outside these results. Saved fixture failures remain in the private evidence. Owned test resources and temporary trust are removed.
The scale measurements above describe
b4fd23b3. The live batching, replay, grant, and socket code remains unchanged at 26774bde. A separate native run on this head passes signed finite reads, signature memo checks, hash rejection, ordered Rust rejection, restored reads, live message rendering, and artifact projection. The run uses two private channels and generated identities at the default quota.Actual healthy minute ticks make zero full roster reads. A controlled non-array response creates roster debt. The next actual tick starts after 60.002 seconds and starts the full reads. The roster reaches verified state after 1.090 seconds, without Retry or reconnect. The capture has 146 native HTTP calls: 144 HTTP 200 and two cancelled HTTP 499. Rust handles 40 claims in 26 commands, including four controlled false results. The 15-minute roster threshold remains covered by focused tests and CI. Cleanup passes. All 130 saved evidence files pass hash verification. No human pass is claimed. The browser broker fix at 60859cc51 preserves a re-added route before buffered status drains. Native source remains unchanged after
26774bde, so the native evidence retains its scope.The public-directory checks retain their tested revision 77748a899. Eight public-search cases pass in Chromium and WebKit in 13.7 seconds. Command:
bin/pnpm exec playwright test tests/browser/global-search.spec.mjs --config=tests/browser/playwright.config.mjs --project=chromium --project=webkit --no-deps --grep 'public search destination'. Later merges change relay recovery, profile accounting, and native cancellation. Public destination ranking is unchanged.No browser journeys are added or removed. Scale, replay order, wire limits, and failure cases stay in Vitest. The existing production broker journey covers mounted UI wiring. The scale case uses 100,000 channels as test data. The relay fixture enforces the 2,048-channel bound for live requests and one channel per replay filter.
Local browser checks pass:
bin/pnpm exec playwright test tests/browser/channel-opening.spec.mjs --config=tests/browser/playwright.config.mjs --project=chromium-measurements --project=webkit-measurements. The macOS run passes eight cases in 1.8 minutes. This covers both channel-opening cases in Chromium and WebKit, plus Chromium scroll checks.Generated with Codex