Conversation
tellaho
force-pushed
the
tho/sidebar-grouping-star
branch
from
September 22, 2026 22:02
0cbb69a to
67146d8
Compare
added 2 commits
September 22, 2026 15:10
Use confirmed host-owned encrypted mute preferences in message notification policy, preserving mentions and unread evidence. Advance channel read state through verified evidence and clear only owned local unread marks in one durable transaction. Expose both actions through the shared row menu with persistence, cancellation, failure recovery and browser coverage. Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Use the shared unread snapshot to offer Mark as Unread only when there is no unread evidence or manual mark. Preserve durable device-local semantics and subscribe only while the menu portal is mounted. Restore focus to the current channel row after a pending action survives cold preference relocation. Cover this ordering with gated browser responses and crop PR screenshots to mute/read actions. Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
tellaho
force-pushed
the
tho/sidebar-mute-read
branch
from
September 22, 2026 22:15
726ad9e to
c86b33c
Compare
added 2 commits
September 23, 2026 09:16
Move New session into the shared row context menu and preserve composer focus. Remove separate row menu controls and mute decoration; use rounded shared-menu highlights. Dismiss mute actions immediately while the session-owned writer saves in the background. Restore confirmed state with explicit retry on failure, ignore superseded completions, and cover persistence, focus and draft retention. Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
Return the actual empty agent-library contract from the production-broker fixture. Exercise New session after mute/read persistence so invalid fixture data cannot crash the composer unnoticed. Signed-off-by: Carl <acda9e433d19dcd0e6b6840f7f4b98f3a56f1fab98049d444c087019e6d36560@buzz.block.builderlab.xyz>
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.
Overview
Category: new-feature
User Impact: Users can start a session, mute a conversation, and mark it read or unread from one uncluttered sidebar menu.
Problem: Conversation actions were split between a context menu and a separate three-dot button, while mute decoration added row noise and saving held the menu open.
Solution: Bring New session into the rounded shared menu, remove the extra row controls, and make Mute/Unmute respond immediately while saving in the background. Read actions reflect current unread evidence and commit through the durable unread owner; failed mute saves restore confirmed state with an explicit Retry/Dismiss notice.
Scope / dependency: Stacked on grouping PR #10 via
tho/sidebar-grouping-starat67146d80b73344220f1dc7991871f1f65169759a, already an ancestor of this head. Starred, Move to… and group assignment belong to that predecessor; they are preserved, not reintroduced here. Session creation/persistence and permissions are unchanged—only its entry point moves. Shared menu styling also applies to other consumers. Sorting and lifecycle actions remain separate.Implemented and maintained by Carl (AI agent) under the operator’s GitHub account. Draft status and stack base are unchanged.
Changes
File changes
dev/relay-broker.mjs
Expose the narrow mute command through existing signed, scoped, serialized preference writes.
dev/sidebar-mutes.mjs
Validate one explicit intent, preserve encrypted fields and unmute tombstones, and confirm the retained result before success.
dev/sidebar-mutes.test.mjs
Cover invalid/foreign heads, budgets, monotonic writes, no-ops, conflicts and publication/readback failures.
dev/sidebar-preference-writes.test.mjs
Exercise Mute through the real HTTP broker, including origin/auth boundaries and failed confirmations.
dev/sidebar-preferences.mjs
Decode the third account-owned preference coordinate within the existing bounded host boundary.
docs/channels.md
Document immediate mute dismissal, background saving, rollback/retry, icon-free rows and the distinct read-action commit behavior.
docs/notifications.md
Document mute eligibility, mention exceptions, pending cancellation and native/sync limits.
docs/sessions/README.md
Document the unified context-menu entry point, keyboard access and focus into retained session drafts.
docs/unread.md
Define channel-read evidence and the explicit clearing matrix, including bounded ownership and local durability.
src/bundled/channels/ChannelReadMenuItem.test.tsx
Cover observed/manual/absent/unknown unread states, command routing, live snapshot updates, pending state, retargeting and StrictMode cleanup in six mounted component tests.
src/bundled/channels/ChannelReadMenuItem.tsx
Subscribe to the shared unread snapshot only while the menu is mounted. Offer exactly one appropriate read action, using the existing device-local manual-unread command.
src/bundled/channels/ChannelSidebarRow.module.css
Remove styling for the redundant three-dot menu while preserving the child-session disclosure.
src/bundled/channels/ChannelSidebarRow.test.tsx
Assert the row has no separate menu button; retain child-session, draft and selection coverage. Real menu-to-composer focus is covered by the browser journey.
src/bundled/channels/ChannelSidebarRow.tsx
Delete the row’s separate New session menu; keep selection, child sessions and draft resumption intact.
src/bundled/channels/ChannelsPage.tsx
Put New session first in the shared context menu and preserve composer focus independently of preference capabilities. Dismiss mute immediately, expose sidebar retry on failure, and keep conditional read actions and identity-based row focus.
src/bundled/channels/sidebar-sections.test.ts
Extend grouping fixtures with the mute projection without changing placement expectations.
src/bundled/channels/useOptimisticMute.test.tsx
Cover immediate projection, confirmation, rollback, explicit retry, rapid reversals, independent channels, StrictMode, retired views and synchronous host failure.
src/bundled/channels/useOptimisticMute.ts
Keep a page-local presentation overlay while the session owns saving. Newer intents supersede older results; failure restores confirmed presentation and offers explicit retry without changing notification truth.
src/bundled/channels/useSidebarPreferences.ts
Expose the session-owned mute capability to the page.
src/features/notifications/messages.test.ts
Cover DM/thread suppression, preserved mentions/unread, failed startup reads and mute/unmute during a permission wait.
src/features/notifications/messages.ts
Apply confirmed mute state in the app-global notification producer, including startup and lifecycle revalidation.
src/features/relay/live-restriction.test.ts
Keep the live-restriction fixture consistent with the added mute projection.
src/features/relay/read-state.ts
Commit an explicit list of owned local clears atomically with the frontier, preserving automatic reading semantics.
src/features/relay/session.ts
Add 14 lines of approved composition-only wiring for the mute writer, lifetime and deadline.
src/features/relay/sidebar-preferences-store.test.ts
Cover confirmed state, shared write ordering, failure/retry, stale reads and session/caller cancellation.
src/features/relay/sidebar-preferences-store.ts
Retain immutable mute state and serialize confirmed writes through the existing preference owner.
src/features/relay/sidebar-preferences.test.ts
Expect the third exact coordinate in production decoder wiring and absent-state projection.
src/features/relay/sidebar-preferences.ts
Validate the legacy channel-mutes schema and expose typed mute intent/projection.
src/features/relay/transport.ts
Discover and invoke the narrow host mute capability, validating its returned projection.
src/features/relay/unread.test.ts
Cover channel-owned clears, latest-reply cuts, later arrivals, access/disposal fences and atomic storage failure/retry.
src/features/relay/unread.ts
Snapshot verified channel evidence at invocation and submit one durable channel-read transaction.
src/features/relay/warm-lifecycle.test.ts
Keep warm-state fixtures consistent with the expanded preference contract.
src/features/relay/warm.test.ts
Keep warm-state fixtures consistent with the expanded preference contract.
src/shared/design-system/DESIGN.md
Describe the shared menu’s roomier inset and pill-shaped highlights.
src/shared/design-system/icons/index.ts
Expose the Phosphor muted-bell icon through the shared gateway; sidebar rows no longer render it.
src/shared/design-system/styles/components.css
Give shared menus an 8px inset and pill-shaped item highlights. Other shared menus inherit the same recipe; global panels and popovers are unchanged.
tests/browser/fixture.mjs
Record encrypted mute publications and match injected failures by exact request URL. Return the real empty agent-library shape so the production-broker session composer can mount.
tests/browser/navigation-groups.spec.mjs
Update keyboard Home/End expectations for New session and conditional read actions while retaining group/star, focus and activity journeys.
tests/browser/navigation-mute-read.spec.mjs
Exercise immediate dismissal with held responses, rollback/retry, encrypted persistence, read/unread reload and unrelated-channel preservation. Retain cold-row-relocation focus coverage and open the session composer through the production broker.
tests/browser/navigation-session-menu.spec.mjs
Exercise right-click and keyboard session creation, Escape focus restoration and retained drafts without preference/read-write host capabilities; assert the three-dot button is absent.
tests/browser/policy-relay.mjs
Require the exact three sidebar preference coordinates in the modeled upstream relay.
Reproduction Steps
Validation and boundaries
5dc4abfff03aaa835a0a59c69d874e7644aa37b8. Clean tracked working tree; remote head verified. All four slice commits retain actual agent authorship and DCO sign-off.git diff --checkpassed against the fetched stack base. Full local scan was not repeated.bin/pnpm exec playwright test --config tests/browser/playwright.config.mjs tests/browser/navigation-mute-read.spec.mjs --project chromium --project webkit --no-deps.1a95a4b(the earlier local fixture-fix snapshot). Only the mute/read test subsequently changed: an explicit menu-closed/focus-return barrier replaced an immediate Escape→reopen race; that full file was rerun at the published head. No product changes followed those passes.[]for the agent library; the real reader already returns{ definitions, identities }. The fixture now matches that contract, and the production-broker journey retains composer coverage.Screenshots / Demos
Fresh captures from the actual built app at
5dc4abf, dark mode with its existing color accent and test conversation data. These are resulting UI states, not synthetic renderings or a component showcase. Sidebar images are cropped to the affected controls. Grouping options shown for context belong to the preceding PR.