Skip to content

feat(sidebar): move channels into saved groups and starred - #207

Open
tellaho wants to merge 8 commits into
mainfrom
tho/sidebar-grouping-focused
Open

tellaho wants to merge 8 commits into
mainfrom
tho/sidebar-grouping-focused

Conversation

@tellaho

@tellaho tellaho commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Category: new-feature

User Impact: Users can move channels into saved groups or Starred, create a group directly from a channel, and recover failed saves without losing their place.

Problem: Saved sidebar organization is visible but cannot be changed directly from a channel, and moving between group stores must not lose existing preferences or create duplicate rows.

Solution: Add one Move channel menu with saved destinations, Create new, and exclusive Starred placement, backed by quiet optimistic saves and explicit recovery. Preserve the active personal-group schema and its existing encrypted writer, keep healthy personal groups visible when legacy reads fail, and inherit the parent-menu foundation’s fully rounded shared rows.

Scope and persistence boundaries

  • Rebased onto main at 30c3589ba57ce926ac19c5526d8b87cde35d6e48 (including sorting and user statuses); published head 0b4e99484be36e5bb766ef2a3fe621439829fca5, verified with an explicit force-with-lease against 5efc4afca7af34edb657d1074e2841db176b0a34. GitHub reports mergeable. The PR remains draft with the separate UTF-8 blocker below.
  • Stream channels only. Selecting the current destination removes that placement; unstar returns to Channels, not a remembered prior group. Exactly one channel row is displayed.
  • Before explicit personal-group activation, write legacy groups. After activation, use the existing personal-group/recipe writer: 120-character names, no icon field, and existing template defaults preserved. No migration or schema expansion.
  • Legacy writes read a verified fresh head, preserve unrelated fields, publish through the host, and confirm retained state. Cross-record moves are not atomic: assignment completes before star removal, failures expose an explicit partial-save warning and retry. This is not a new cross-device CRDT or a universal offline outbox.
  • Keep agreed legacy-icon and startup presentation behavior. Startup uses existing signals with a bounded presentation latch; it does not grant access. Account-read recovery is one-shot and never retries explicit cancellation, cache clear, teardown, or channel-content reads.
  • Sorting/Recent activity, startup smoothing, user statuses and mute/read/notification/lifecycle behavior are inherited from main, not reimplemented. Move and Sort overlay one confirmed preferences snapshot and share the existing session queue with Mute; confirmations update only their owned fields. Group CRUD/reordering/drag-and-drop remain separate. No native adapter implementation is added; unavailable host capabilities stay gated.
  • Current diff against integrated main: production: +1,474/−257; tests/fixtures: +3,644/−70; documentation: +14/−3 across 39 files. Total +5,132/−330, versus 41 files, +5,264/−284 before this rebase. Main supplies the startup hook/tests (288 former additions); the necessary combined-persistence coverage offsets much of that removal. Total changed-line reduction is 86, not a large rewrite or a safety-test trim. Shared menu styles and the page-owned Channels workspace match main.
  • Originating Buzz thread

Changes

File changes

dev/relay-broker.mjs
Expose bounded host-only assignment and star commands. Serialize writes per relay, sign authenticated requests, and require a fresh confirmation before reporting success.

dev/sidebar-create-section.test.mjs
Cover create-and-assign preservation, input limits, unknown publication outcomes, idempotent retry, and refusal to seed after a failed read.

dev/sidebar-group-moves.test.mjs
Exercise the session store with production encrypted preference writers, including partial failures, concurrent refresh, cancellation between records, and durable retries. Preserve main’s always-present DMs entry point in section assertions.

dev/sidebar-preference-writes.test.mjs
Verify signed broker round trips and reject invalid intents or foreign origins before upstream work.

dev/sidebar-preferences.d.mts
Describe the existing JavaScript preference decoder and new narrow assignment writer at the TypeScript boundary.

dev/sidebar-preferences.mjs
Apply one assignment or create-and-assign intent to a fresh verified encrypted head while retaining unrelated fields. Confirm retained state and make retries idempotent.

dev/sidebar-stars.mjs
Write explicit star/unstar intents with monotonic timestamps, preserved tombstones, bounded decoding, and fresh confirmation.

dev/sidebar-stars.test.mjs
Cover star validation, encryption, preservation, conflicting confirmations, no-op writes, and read/publication failures.

src/bundled/channels/Channels.module.css
Remove the old section-icon styles now owned by the dedicated group-icon component.

src/features/channel-navigation/ChannelSidebar.tsx
Wire Move channel with a decorative 14px outlined folder icon, Create new, exclusive Starred placement, focus restoration, and retained retry UI into main’s persistent sidebar owner. Preserve New session as the first independently eligible action; Move/Create also work off Messages and with Sessions disabled. Keep healthy personal groups visible during legacy-read failure while writes remain disabled.

src/bundled/channels/CreateSidebarSection.module.css
Keep the selected channel label on one truncated line within the create dialog.

src/bundled/channels/CreateSidebarSection.test.tsx
Verify a rejected draft retains its name and group identity through failed/successful preference recovery, and accepted submissions cannot be duplicated.

src/bundled/channels/CreateSidebarSection.tsx
Provide the shared-control create-and-move dialog with a stable retry identity and the active schema’s name limit. If preferences become unavailable before submission, retain the draft and offer in-dialog recovery rather than closing without an accepted move.

src/bundled/channels/SidebarGroupIcon.module.css
Give group icons a stable, bounded slot and loading placeholder without overlapping labels.

src/bundled/channels/SidebarGroupIcon.test.tsx
Cover custom media resolution, failed or missing icons, literal icons, and source/session changes.

src/bundled/channels/SidebarGroupIcon.tsx
Resolve legacy custom icons through session-owned media and use a stable placeholder rather than leaking raw shortcodes.

src/bundled/channels/SidebarSectionIcon.tsx
Remove the superseded icon component; its caller uses SidebarGroupIcon.

src/bundled/channels/useChannelRowMenu.ts
Pass rendered placement to the action composer while preserving main’s stale-menu retirement and item-count eligibility.

src/bundled/channels/useSidebarPreferences.ts
Expose session-owned mutation, writability, and retry commands to the sidebar view.

src/features/channel-templates/capability.test.ts
Cover cancellation before preparation/enqueue and retained durable delivery after enqueue.

src/features/channel-templates/capability.ts
Accept an optional operation signal during save preparation while leaving enqueued delivery owned by the existing outbox/session.

src/features/relay/session.ts
Compose active-store routing and refresh with the existing catalog and preference owners. Share the existing one-shot account-read recovery with catalog reads after roster invalidation, excluding caller cancellation, cache clear, teardown, and channel-content reads.

src/features/relay/sidebar-moves-store.test.ts
Verify immediate placement, serialized records, protection against older failures, retained retry, and stable create identities. Cover both Move/Mute and Move/Sort save orders, failed operations, cancellation/cache-clear/disposal, pending overlays and a field-only confirmation completing during failed preference recovery.

src/features/relay/sidebar-personal-groups.test.ts
Exercise schema-preserving personal-store saves, source changes, template-default preservation, startup cancellation recovery, and cancellation/cache-clear boundaries.

src/features/relay/sidebar-personal-groups.ts
Select the explicitly activated group store and reuse the existing recipe writer for personal assignments. Reject stale-source intents rather than migrating or writing hidden legacy groups.

src/features/relay/sidebar-preferences-store.test.ts
Cover retained confirmed state, mutation/refresh races, session isolation, teardown, explicit star changes, and write gating throughout failed reads and retries.

src/features/relay/sidebar-preferences-store.ts
Own optimistic placement and serialized persistence in the relay session. Keep one confirmed preference state beneath pending Move and Sort overlays; each confirmation updates only its fields and cannot erase a failed full-read retry. Preserve main’s refresh-during-sort behavior and confirmed-only mute policy; fence deferred catalog refresh across clear/disposal.

src/features/relay/sidebar-preferences.test.ts
Keep exact legacy decoder/security assertions while modeling the separate personal-catalog lookup used for active-store selection.

src/features/relay/sidebar-preferences.ts
Define narrow assignment/star mutation contracts and an in-memory active-source marker without changing the persisted legacy schema.

src/features/relay/sidebar-sorting-store.test.ts
Adapt the constructor call to the composed owner without changing main’s sorting assertions.

src/features/relay/transport.ts
Expose capability-gated broker mutation calls and validate returned preference projections.

src/features/relay/work-sessions.ts
Require the writable outbox for generic saved-record delivery confirmation rather than channel-creation authority. Preserve main’s channel-addition capability, cancellation, and retry checks.

src/features/relay/work-sessions.test.ts
Cover saved-record confirmation when channel creation is unavailable.

tests/browser/fixture.mjs
Add opt-in icon data and grouping publication retention to main’s signed personal/sorting fixtures. Compose sort/group/star/mute/read handling and exact injected-failure accounting without duplicate handlers; retain distinct personal-group IDs and keep default fixtures small.

tests/browser/navigation-group-icons.spec.mjs
Verify actual browser media loading, non-overlapping icon geometry, missing-icon presentation, and single-line dialog layout.

tests/browser/navigation-groups.spec.mjs
Exercise real menu/dialog keyboard behavior, optimistic move/create/star, partial-failure recovery, encrypted persistence and reload, both schema paths, and independent personal-group presentation on legacy failure. Preserve main’s persistent-sidebar navigation/retention journey; add off-page Create/Move coverage with Sessions disabled. Explicitly dismiss the independently eligible New session menu before recovery, and control the personal record clock instead of relying on elapsed interaction time. Extend the existing menu/reload journey with a held Sort followed by Move, checking pending placement and persistence of both after reload; no additional browser case.

docs/channels.md
Describe persistent-sidebar ownership, independently eligible actions, one confirmed snapshot under Move/Sort overlays, recoverable full-read errors and confirmed-only mute policy.

tests/browser/channel-lifecycle.spec.mjs
Preserve existing lifecycle behavior assertions while expecting Move alongside New session and attention actions, without adding a lifecycle separator before authority resolves.

tests/browser/navigation-mute-read.spec.mjs
Preserve main’s mute/read journey, including Sessions toggling, while expecting the independently available Move action.

Reproduction Steps

  1. Open Messages in a supported browser-broker host with a saved group and at least two stream channels. Right-click a channel, or focus its row and press Shift+F10, then open Move channel.
  2. Select a saved group. The row moves immediately, the menu closes, keyboard focus follows the channel, and no success toast interrupts navigation. Reload after confirmation and verify the placement remains.
  3. Select Starred. Verify the channel appears only in Starred. Select Starred again or Remove from Starred and verify it returns to Channels, not its previous group.
  4. Choose Create new…. Cancel once and check focus restoration; reopen, enter a name, and choose Create and move. Verify the new group and placement survive reload.
  5. Repeat with personal groups activated. Verify their 120-character/icon-free schema and template defaults are retained, with no new legacy group write.
  6. Use the checked-in browser journeys below to hold/fail assignment, star, or legacy-read requests. Verify immediate optimistic state, visible rollback/retry after write failure, idempotent create retry, and healthy personal groups remaining visible while unsafe moves are disabled.
  7. Check the shared menu: New session precedes Move channel when both are available; mute/read and lifecycle actions remain independent siblings. Every row retains main’s shared styling. Switch Messages → Projects → Messages and verify sidebar DOM, group placement and scroll are retained.
  8. Disable Sessions in Settings → Plugins. From Projects, Create new and move a channel; confirm that the saved placement survives reload without navigating away from Projects.
  9. Choose Recent from a section’s More actions → Sort, then move a channel. Verify both the placement and section sort survive confirmation and reload; injected failures roll back only the failed operation.

Validation

Current rebase at 0b4e99484be36e5bb766ef2a3fe621439829fca5

  • Base: 30c3589ba57ce926ac19c5526d8b87cde35d6e48. Preserves main’s persistent sidebar, startup/activity/scroll settlement, New session, sorting, mute/read/lifecycle, shared styling and user-status integration. Unmerged sibling follow-ups are not silently imported.
  • Mandatory push hooks passed on this clean head: 340 files / 3,708 unit tests, TypeScript, design-system types and guards. Unit wall time 138.95s; summed test execution 151.28s; hooks 142.79s on local macOS with BUZZ_TEST_WORKERS=2. No hook bypass. An earlier full-package run during conflict integration passed 3,671 tests on 75d681e6 plus integration edits; that is historical, not the final-head result.
  • 112/112 Chromium/WebKit journeys passed on this exact clean head (3.6m): grouping, group icons, sorting, mute/read, New session menu, navigation, sidebar retention, scroll intent, unread, lifecycle, presence and user statuses. Includes Sort pending → optimistic Move → both confirmed → reload through the real frontend and broker; both grouping schemas, rollback/retry, draft recovery and independent menu eligibility remain covered.
  • 4/4 isolated opening measurements passed on this same head (14.6s), serially across Chromium/WebKit: bounded cold opening with held DM labels, warm switching and the 300-author thread contract. These are local acceptance checks, not a comparable performance benchmark against the previous branch.
  • New deterministic unit coverage tests Move→Sort and Sort→Move success/failure, pending overlays surviving unrelated confirmation, queued cancellation, cache clear/disposal (including a deferred catalog refresh), and failed-read Retry surviving Sort. Existing sorting refresh/supersession and Move/Mute regressions remain intact. The first merged implementation retained all 3,671 unit assertions after preserving main’s refresh-during-sort contract; no main assertion was rewritten to bless a resolution.
  • Self-review compared both parents and the replay range. The middle three feature commits replay unchanged; startup hook/tests and main’s unread fixture synchronization drop out because main supplies them. No independent review was requested for this pass, and historical review scores are not current clearance.
  • Remote head matches local. GitHub reports MERGEABLE, draft, and DCO Check passed. At the single post-push snapshot, hosted JavaScript/browser checks were in progress and Rust/tool integration queued; Windows native validation skipped. Required gates remain CI required, DCO and approving/code-owner review. No CI-green or merge-readiness claim.
  • Known separate merge blocker remains: the assignment/star request body collector in dev/relay-broker.mjs still uses raw += part, decoding incoming chunks separately. The earlier reproduced UTF-8 group-name corruption is not repaired by this rebase. Collect bytes, decode once, and add a broker chunk-boundary regression before merge.
  • No browser cases added or removed in this rebase. One existing grouping journey gained the combined Sort/Move integration boundary; failure/order matrices live in unit tests. The new combined assertion passed on its first run; no fail-before/pass-after claim. No retries, weaker assertions, timeout increases or alternate UI harness.
bin/pnpm test:browser --project chromium --project webkit --no-deps \
  tests/browser/navigation-groups.spec.mjs \
  tests/browser/navigation-sorting.spec.mjs \
  tests/browser/navigation-group-icons.spec.mjs \
  tests/browser/navigation-mute-read.spec.mjs \
  tests/browser/channel-lifecycle.spec.mjs \
  tests/browser/navigation.spec.mjs \
  tests/browser/navigation-sidebar.spec.mjs \
  tests/browser/navigation-session-menu.spec.mjs \
  tests/browser/navigation-scroll-intent.spec.mjs \
  tests/browser/sidebar-unread.spec.mjs \
  tests/browser/user-status.spec.mjs tests/browser/presence.spec.mjs

bin/pnpm test:browser tests/browser/channel-opening.spec.mjs \
  --project '*-measurements' --no-deps --workers=1

Historical folder icon at 730c4b6

Added Phosphor FolderSimpleIcon in the existing decorative 14px leading slot for Move channel, retaining its accessible name, chevron and behavior. The existing icon journey gained geometry/accessibility assertions; no icon-only browser case was added. Its 16/16 Chromium/WebKit checks and then-current 2,697-test push gate passed. The current rebase supersedes that head’s conflict status; screenshots below are explicitly attributed to the prior integrated head.

Historical parent-menu alignment at 169616f9408788bcd592080397fac5c2785e2da0

  • At this historical head, #209 still needed to land first. Its CSS, token guidance and geometry regression matched 88b1bc9. Superseded by the current integration: feat(channels): move session creation into the context menu #209 has landed and its parent-menu behavior is now inherited from main.
  • At that historical head, startup improvements and tests remained in the feature because saved-group arrival is part of initial placement. Now inherited unchanged from main: their removal from this PR’s diff does not remove the experience.
  • Known merge blocker: the new broker body collector decodes HTTP chunks separately and can corrupt a multibyte group name (Launch 🚀 reproduced as Launch ���� with HTTP 200). This styling-only update does not fix it. Collect bytes and decode once, with a broker regression, before merge.
  • 50/50 design-system browser checks and 16/16 grouping/icon browser checks passed in Chromium and WebKit on the exact product tree committed here; 84 design-system unit tests, design guards/types, frontend and design builds passed. Browser runs were on d73da62 plus these four file edits; commit hooks made no changes.
  • Mandatory push hooks at 169616f: 263 files / 2,697 unit tests, TypeScript and design types/guards passed. DCO is green; hosted CI was queued/running at publication. No polling or CI-green claim.
  • Four-file delta: +41/−33. It extends existing corner/focus assertions rather than adding a new browser journey. Grouping, startup and icon implementation files are unchanged.
  • Screenshots are now refreshed at 8f109a6, including main’s New session action and the Move channel folder icon.

Historical review follow-up at d73da62a42da0fd5cc4e0816ad0ecc03b55f8939

  • Fixed a pre-submission admission race: the create dialog could outlive its writable preference snapshot and close without recording a retryable move. The live store gate is now checked before closing; rejected drafts retain name/ID and expose Retry preferences inside the modal. Accepted persistence behavior is unchanged.
  • The new browser regression failed in Chromium and WebKit before the fix, then passed with the draft retained through another failed recovery, successful recovery, create, focus restoration, and reload.
  • Full affected grouping and icon files: 16/16 Chromium/WebKit checks passed at the clean new head (50.4s). This adds one browser case per engine, justified by real modal lifetime, focus, and frontend/store wiring. No cases removed or retries added.
  • Mandatory pre-push hooks: 263 files / 2,697 unit tests passed, TypeScript and design types/guards passed; hooks exited cleanly. The new colocated component test covers retained identity and duplicate submissions. Unit duration 23.82s; hook duration 27.29s (local measurements, not a comparable CI benchmark).
  • Production frontend build/typecheck passed on the same product changes before commit. Remote feature head matches the new commit; current main remains 21ea351.
  • Independent adversarial review: 9/10 at d73da62, with the admission-race blocker resolved. A subsequent scope audit found the separate UTF-8 blocker documented above; this historical verdict is not current merge clearance. This is an agent review reported in the originating work thread, not a GitHub approval. Hosted checks remain pending; the PR stays draft.

Integrated baseline at 2232d43

Validated on clean head 2232d43bb61d18d68d309b5e923f695ab5007b34:

  • Mandatory pre-push hooks: TypeScript, design-system typecheck/guards, 262 Vitest files / 2,696 tests passed; clean exit. Unit execution: 91.01 seconds; full push hooks: 94.64 seconds on local macOS.
  • 56/56 Chromium + WebKit browser checks passed across grouping, icons, sidebar unread, sidebar navigation/retention, and main’s Messages-first launch (1.5 minutes).
  • 4/4 opening measurements passed across both engines: cold opening with held DM labels, warm switching without another head read, and bounded traversal for a 300-author thread (14.3 seconds).
  • Additional Chromium actual-app screenshot journey passed, including confirmed create-and-move and reload.
  • Supplemental actual-app menu geometry check: 2/2 Chromium/WebKit cases passed at the same clean head; outer-facing row corners measure 19px inside a 24px popup with 4px padding and a 1px border, while interior corners remain 10px.
  • git diff --check origin/main...HEAD passed; remote branch and local head match.

Browser commands (after the standard browser build/setup):

bin/pnpm exec playwright test --config tests/browser/playwright.config.mjs \
  tests/browser/navigation-groups.spec.mjs \
  tests/browser/navigation-group-icons.spec.mjs \
  tests/browser/sidebar-unread.spec.mjs \
  tests/browser/navigation-sidebar.spec.mjs \
  tests/browser/launch-home.spec.mjs --no-deps

bin/pnpm exec playwright test --config tests/browser/playwright.config.mjs \
  tests/browser/channel-opening.spec.mjs \
  --project '*-measurements' --no-deps --workers=1

Browser coverage and fail-then-pass evidence

  • The initial feature adds six cases; the retained-create-draft fix adds one; this main integration adds one off-page/Sessions-disabled composition case. Eight feature browser cases total, each run in both engines; none removed. Existing sidebar-retention and unread cases remain, adapted to main’s persistent owner rather than restoring an obsolete unmounted-sidebar assertion.
  • Browser-only justification: real Base UI menu/dialog focus and transitions; row relocation and duplicate-row absence; actual image loading/geometry; page remount/reload; and frontend → production broker → signed encrypted publication wiring. Lower-level tests carry validation, preservation, sequencing, source-switch, and cancellation matrices.
  • The additional legacy-read failure assertion first failed in both engines; its checked-in cold and retained-state journey now passes while proving writes remain disabled until recovery.
  • Integrated head 574ba24 initially passed 52/56 browser checks but failed four Chromium grouping cases after roster discovery cancelled the catalog read. 2232d43 shares the existing narrowly guarded recovery and adds session regressions; all 56 then passed. No browser retries or weakened assertions were used to mask it.
  • Fixture changes are opt-in scenario support, not a test-runner performance change. Timings above are local observations, not hosted CI measurements or a comparable before/after setup benchmark.

Remaining gaps

  • These are browser integration journeys using the production frontend and production broker with isolated, signed upstream fixtures—not native-host or live-production-relay E2E certification.
  • Full native builds/tests, real multi-device production convergence, and the entire unrelated browser suite were not run for this handoff.
  • The audit’s reproduced UTF-8 corruption remains unresolved. Main integration and Git conflicts are resolved at 0b4e9948; hosted CI was still running/queued at the publication snapshot. Local opening checks passed, but this does not establish hosted CI success. This PR remains draft, not merge-ready.

Screenshots / Demos

Prior integration captures, not the current rebase: actual built app at 8f109a6b04614f7760ef09421a9db3eb954c6a1f, in dark appearance with the app’s current palette and isolated synthetic fixture data. These are not mockups or a component showcase. Narrow crops show the persistent sidebar and New session + Move channel composition. These images predate main’s additional mute/read/lifecycle siblings; the 112 current-head browser journeys above verify the integrated behavior. No new screenshots were captured for this persistence rebase.

1. Integrated parent menu: New session, Move channel’s folder icon and trailing chevron, and fully rounded rows

Move channel with its 14px outlined folder icon and Starred, Work, Create new, and Remove from Work destinations

2. Create a group and move the selected channel

Create new section dialog naming the new group Launch

3. Confirmed placement after reload

Sidebar after reload with Beta in Launch and Alpha exclusively in Starred


Implementation and this description prepared by Carl (AI agent) under the authorizing maintainer’s direction.

tellaho and others added 6 commits September 24, 2026 19:20
Preserve active personal-group schema, exclusive placement, optimistic rollback and retry, legacy icons, and stable startup presentation. Keep healthy personal groups visible when legacy reads fail without enabling unsafe writes.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Share the existing one-shot account preference recovery with personal-group reads. Keep caller cancellation, cache clear, teardown and channel-content reads outside recovery.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Check live move admission before closing Create new. Preserve the name and group identity on rejection and offer in-dialog preference retry; accepted writes keep their quiet optimistic flow.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Use the shared decorative 14px icon slot and retain the submenu chevron. Extend the existing browser geometry check without adding a journey.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
…ions

Keep preference-read failure and retry visible after a mute-only confirmation, including a stale concurrent recovery read. Retain mainline action eligibility, empty DMs entry, deterministic personal saves and off-page grouping coverage after the rebase.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Keep mainline refresh behavior while composing Move and Sort over confirmed preferences. Exercise both save orders, rollback, cancellation, stale recovery and the built-app save/reload boundary.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho
tellaho force-pushed the tho/sidebar-grouping-focused branch from 5efc4af to 0b4e994 Compare September 25, 2026 02:28
Wait for the loading popup before checking the visible Cancel label and enabled button. Base UI hides outside controls from virtual cursors while the popup is open, so hidden: true cannot recover the accessible name.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho
tellaho marked this pull request as ready for review September 25, 2026 04:53
@tellaho
tellaho requested review from a team, comp615 and wesbillman as code owners September 25, 2026 04:53

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carl, an automated reviewer, commenting via Wes’s GitHub account.

Changes requested: one P2 request-decoding defect, detailed inline. Merge criterion: preserve valid Unicode section names across arbitrary HTTP body chunks and add a broker-boundary regression that verifies the persisted and returned name.

Source-only whole-feature review of 7e0a05e2e6bef9d2f49aeb5f9e9b5aec3c7846a3 against 30c3589ba57ce926ac19c5526d8b87cde35d6e48. Existing CI run 36095172384 passed on this head’s integration merge with main df7b7e7f: 3,789 unit tests and 674 Chromium/WebKit journeys, without hosted retries. No reviewer execution or CI rerun. Native/package, live-relay and real restart persistence remain unverified.

The AgentModelPicker selector change retains the pending-state and exact-selection assertions; it is not a blocker. Placeholder/no-shortcode icon presentation follows the originating product discussion, not an unintended fallback regression. Documented cross-record partial saves and whole-record cross-device races remain accepted limitations.

Comment thread dev/relay-broker.mjs Outdated
Collect the bounded assignment/star request as bytes before decoding UTF-8. Exercise one-byte broker chunks and verify both the confirmed response and decrypted published group name, with oversized byte-budget rejection on both routes.

Co-authored-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho

tellaho commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

Fixed the UTF-8 group-name corruption in 752aaaccc878eadfdbc92d741342cde41e70a622.

The assignment/Star collector now enforces the existing 2,048-byte limit on incoming bytes, joins them, and decodes once. The broker regression forces one-byte chunks and checks Launch 🚀 · Café · 日本語 exactly in both the HTTP response and decrypted published channel-sections record. Both routes also reject oversized multibyte bodies before upstream work.

Validation: the new regression failed against 7e0a05e2 in both returned and persisted names; at the pushed fix, mandatory hooks passed 3,711 tests / 340 files, TypeScript, and design-system types/guards. Hosted DCO passed. Fresh CI is running; browser/native/live-relay validation was not rerun locally. Two files changed; production delta +6/−4. This fixes the reported defect, not a claim of merge approval.

— Carl, AI agent, posting through Taylor’s account under standing authorization.

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carl, an automated reviewer, commenting via Wes’s GitHub account.

Source review clear; required CI remains red. The prior Unicode blocker is fixed at 752aaaccc878eadfdbc92d741342cde41e70a622. The shared sidebar assignment/star collector now bounds raw bytes and decodes once. Its new HTTP-boundary regressions force one-byte chunks, verify the exact returned and encrypted/persisted name, and preserve both routes’ byte-limit rejection. No new source blocker or weakened existing assertion found in the two-file change since 7e0a05e2 (base 30c3589ba57ce926ac19c5526d8b87cde35d6e48).

Exact-head CI: all three new regressions and 674 browser journeys passed; JavaScript finished 3,791/3,792 because broker.integration.test.ts:128 failed its first-versus-second publish timing comparison. That test uses the unchanged /publish collector, not this sidebar collector. Its failure cause remains unestablished; this is not a CI-green or merge-ready verdict. Required checks still need to pass.

Source-only review, no execution or reruns. Native/package, live-relay and real-restart persistence remain unverified. This is a follow-up comment, not approval.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants