Skip to content

Add editing, deletion and read controls to message menus - #189

Open
morgmart wants to merge 11 commits into
mainfrom
morganm/message-management
Open

morgmart wants to merge 11 commits into
mainfrom
morganm/message-management

Conversation

@morgmart

@morgmart morgmart commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

What this does

Adds own-message editing, confirmed deletion, and one immediate read/unread action to the shared message menu. Editing uses the existing conversation composer, not a separate editor dialog. Channel, DM, thread, session, and media-review surfaces share the same management and delivery owners.

  • Menu Edit and Up-arrow editing use the same handler. Cancel and successful save restore the unsent text, undo checkpoint, and queued files. Unsent files stay hidden while editing another message.
  • Existing attachment links and bound mention identities are preserved. Edits do not add notification recipients. Attachment editing is not included.
  • Submitting an empty text-only edit opens deletion confirmation. An edit of a message with original attachments instead explains that attachment links must remain unchanged; explicit Delete remains available.
  • Deletion explains that people may retain copies, uses the existing outbox, and restores focus to the surviving composer. Failed or uncertain updates retain recovery controls outside the message row.
  • Mark read/unread is a single immediate menu action, not a dialog or isolated unread label. It applies to the selected verified message and its loaded reply subtree through the existing unread owner.

Unread behavior and limits

Manual message unread is device-local. During a channel visit it participates in the same predicate used by menu labels, row attention, and observed counts. Leaving ends that per-visit overlay but retains a local sidebar hint; reopening reconciles that hint without clearing a separately chosen channel-unread mark. Own messages remain excluded from notification unread, matching Old Buzz.

Operations are serialized per channel, fenced against navigation and access changes, and persist subtree reads atomically. Reading one subtree cannot clear another's force. A host without read-state signing can clear a local force only when existing frontiers already cover foreign messages; new read evidence produces an honest unsupported error. Own replies do not require invented frontiers.

No second editor, outbox, unread engine, persistence store, or relay protocol is introduced.

Scope and size

Integrated main through df7b7e7f, preserving its current sidebar, channel actions, status display and attachment provenance. The complete PR delta is 34 files, +3,002 / -143.

Uses existing composer, outbox, deletion-event and unread ownership. The separate edit/read dialogs were removed rather than maintained alongside those owners. New main behavior for channel context menus, profile actions, identity naming, media and panel stacking is retained.

Owned-agent edit/delete remains separate: BOT-2065. Follow/send-to-channel, reminders, reporting, fuller attachment editing and notification-recipient changes are out of scope. No merge is requested or performed.

Reviewer findings addressed

  • Unchanged mention edits: capture the exact initial editor seed once, then close without publishing when submission equals that seed or the original source. Current-row availability and source-staleness checks still run first. Cancel clears the seed; retry continues using the existing operation. Regression coverage includes menu and ArrowUp entry, bound mentions, preserved attachment source, draft/focus restoration, and unchanged submissions against changed/deleted targets. The ArrowUp regression failed before the fix and passed afterward.

  • Standalone composer-links crash: the eager unread row consumer was removed in the earlier correction. The complete existing composer-links journey passes in both engines after this rebase, with its assertions retained.

  • Mention chips preserve the exact underlying identity links without adding notification recipients. Completed mention text does not show suggestions solely because directory loading failed; active queries retain recovery UI.

  • Exact-session editing: the existing edit scope reads the exact view’s current row without filling the channel timeline. Real menu-to-composer tests cover save, stale source, deletion and navigation abort; all four failed at edit entry before the fix and pass afterward.

  • Own-message unread reversal: expose existing forced-message intent separately from notification unread and keep message snapshots reactive to that intent. The menu can clear what it sets; own rows remain excluded from notification counts. Independent channel intent and subtree isolation remain covered.

  • Terminal mention recovery: reject a completed valid identity-link source before mounting completion. Genuine searches remain available. A mounted composer with missing profile data closes unchanged editing on Enter without publication or directory refresh; the old matcher reproduced the failure.

  • Replied directly to all five inline findings and resolved their threads after push; GitHub readback verified both replies and resolution. This does not dismiss the changes-requested review or imply approval.

Verification

Pushed head: e778f488f0146bc7d36bae985044f4a3a28e6175. Remote head verified; working tree clean.

Latest correction: explicit-intent ordering finding fixed by routing local unread, local clear and explicit mark-through into the existing per-channel queue. Evidence/frontier and access epoch stay captured at invocation. Three held-save regressions failed before the fix (channel/thread/message unread erased by an older queued channel read); all pass with the fix. Nine added cases cover both action orders and queued cache clear, disposal and access revoke/regrant. Mongo independently reviewed the final two-file change with no remaining finding.

Exact-head mandatory push checks passed: TypeScript, 1,871 tests across 132 complete files, design types and guards; formatting/lint passed. Two workers; 105.05s test wall time, 133.69s summed execution. Existing screenshots remain representative; this correction changes ordering under delayed storage, not visible layout. Hosted CI and reviewer re-review remain pending.

Previous integration at fb5b3e60: workflow PR #193 landed after the prior conflict repair, creating a test-addition conflict. Both workflow and message-edit tests are retained; production code merged automatically. Exact-head push checks passed: TypeScript, 1,862 tests across 132 complete files, design types and guards; formatting/lint passed. Unit-test wall time 107.12s, summed execution 133.99s.

Previous integration validation at 91a99b15 (its hosted CI also passed):

  • Exact-head mandatory push gate passed: TypeScript, 1,832 tests across 128 complete files, design types and guards. Commit formatting/lint passed. Two workers; 108.99s unit-test wall time, 134.97s summed test execution.
  • 14 Chromium/WebKit cases passed on the resolved merge before commit formatting across complete message-management, navigation-mute-read, composer-links and session-navigation files. No retries.
  • The focused read-state, unread and broker API files passed 139 tests before formatting.
  • Channel-wide read now atomically clears its saved message-force hint, then releases active message forces after storage succeeds. Per-channel serialization preserves later message intent; captured frontiers preserve later arrivals. New coverage includes own messages, failed/held saves, other-channel isolation and later unread actions. Mongo independently inspected this reconciliation and reported no remaining issue in that scope.

Earlier-head validation (historical, not a claim about the latest commit):

  • Mandatory push gate passed on this exact head: TypeScript, 1,676 tests across 118 complete files, design types and all design-system guards. Normal commit formatting/lint passed. No hooks bypassed or assertions relaxed. Two test workers; 84.46s test-run wall time, 110.71s summed test execution.
  • 20 Chromium/WebKit cases passed across complete management, message-actions, composer-links and session-navigation files, two workers, no retries. These ran at d3eac2c3 plus the resolved main merge and interaction fixes before final formatting; the terminal query guard was subsequently tightened to require the opening bracket, and test expectations were aligned with main’s attachment-source argument. Final production changes are covered by the exact-head push gate, not a claimed browser rerun.
  • Exact-session integration and lifecycle files passed 17 tests; unread/management files passed 61; mention regression files passed 32. The final complete composer file passed in the push gate after aligning two older assertions with main’s required attachment provenance argument.
  • Princess Donut implemented and reproduced the terminal-mention regression; Mongo implemented the own-message unread fix; Carl reviewed and integrated both. Mordecai independently reviewed exact-session ownership, lifecycle cleanup, main sidebar integration and attachment provenance. Reviews were reported in Buzz.
  • Three browser journeys added relative to main (six engine cases), none removed: channel/thread management, thread-deletion focus and DM permissions/editing. Browser-only purpose: portal/focus behavior and real application wiring; the existing management case also covers narrow/intermediate/wide mention geometry and serialized identity preservation. State and recovery matrices stay in component/owner tests. Earlier focus and mention-display regressions have fail-then-pass evidence.

Remaining acceptance gates

Hosted checks for e778f488 are pending after the ordering fix. GitHub still shows CHANGES_REQUESTED until the reviewer re-reviews the correction. Manual native/live acceptance limitations below remain; nothing has been merged.

Native GUI and deployed-relay acceptance, adversarial live foreign-target writes, restored edit/delete outbox recovery through a full process restart, and media-review deletion focus in a real browser remain unverified. Browser upstream relay policy is modeled; it is not proof of deployed relay enforcement. Original-attachment protection is exercised with mounted fixtures, not a live uploaded-media editing journey. No live messages were edited or deleted during automated validation.

Screenshots

Captured from head 087114e8434750cf1f5cf74a59d641e59ab4ceb4 in Chromium using synthetic browser fixtures. The relay is modeled; these are not native-app or live-relay acceptance evidence. All three capture journeys passed.

Editing in the existing composer

An existing mention remains a person chip while editing. The same conversation composer supplies save and cancel.

Editing a message in the conversation composer, with its existing mention preserved

Delete confirmation on a narrow viewport

Deletion requires confirmation and explains that other people may retain copies.

Narrow-screen delete confirmation with Cancel and Delete actions and retained-copy warning

@morgmart
morgmart force-pushed the morganm/message-reactions branch 2 times, most recently from b618613 to 37b5107 Compare September 23, 2026 23:57
Base automatically changed from morganm/message-reactions to main September 24, 2026 02:54
@morgmart
morgmart force-pushed the morganm/message-management branch from 052b67d to 58a4678 Compare September 24, 2026 02:59
@morgmart
morgmart marked this pull request as ready for review September 24, 2026 03:00
@morgmart
morgmart requested review from a team, comp615 and wesbillman as code owners September 24, 2026 03:00

@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 introduced integration failure, detailed inline. Restore the standalone message/composer fixture’s session contract and the existing composer-links journey in both engines without weakening its assertions.

Reviewed 58a467871293d6d01cebab91b73b6458334ead1f against merge-base 12a957c238771545dee57e9b83f26171074578ec: shared channels/DMs/threads, edit/delete authority and recovery, attachment/mention handling, and device-local read marks. Source-only on Blox; no checkout, installs, builds or tests executed. Existing exact-head CI run 35949582227 fails Chromium/WebKit composer-links; both retained traces identify the new unread component as the cause. JavaScript and Rust/tool integration passed. Native/real-relay acceptance, assistive-technology focus behavior and cold-profile edit timing remain unverified; this is not release certification.

Comment thread src/features/messages/MessageRow.tsx Outdated
@morgmart
morgmart force-pushed the morganm/message-management branch from 58a4678 to fdab6d9 Compare September 24, 2026 15:29

@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 unintended-write regression, detailed inline. Keep no-change edits silent for messages with bound mentions while preserving the new mention chips; extend the existing unchanged-content regression with that case.

The prior composer-links render crash is repaired by removing the eager unread row consumer. The rebased changes were reviewed against 597c09719b51ca84ec58baa5c2d57f87dd7c40f6, including edit/delete recovery, attachment/mention preservation and unread ownership across channel/DM/thread/session/media-review wiring. Source-only on Blox: no checkout, installs, builds or tests executed.

Validation remains incomplete: head 99f5834a530fe6ec57709b81f187820aeff85d39 has passing DCO/Semgrep/zizmor but no GitHub Actions run. Parent fdab6d9748405b4fcc319c72b6785a9f7524ed91 CI #968 passed composer-links in Chromium and WebKit, but failed the separate new-message.spec.mjs:355 disabled-trigger placeholder assertion in both engines. That failure is not attributed to this diff. Current/merged-head CI and native/live-relay acceptance remain gates; source review is not release certification.

Comment thread src/features/messages/useMessageEdit.ts
Carl added 7 commits September 24, 2026 13:48
Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>
Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>
Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>
Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>
Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>
Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>
Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>
@morgmart
morgmart force-pushed the morganm/message-management branch from 99f5834 to d3eac2c Compare September 24, 2026 20:56

@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: three P2 interaction defects, detailed inline. Wire exact-session targets into the edit owner, make own-row manual unread reversible without counting own messages as notification unread, and exclude completed terminal mention links from recovery completions.

The previous unchanged-bound-mention write is repaired: the captured editor seed closes silently only after current-row/stale-source checks, with focused coverage. Reviewed d3eac2c3b043a573ebc8678976260b719246d4db against pinned base 1e15d5d33b6b89c673ceefabeb55d1e5dbb8d579 across channel/DM/thread/session/media edit, deletion/recovery and read-state ownership. Independent mention/completion analysis was integrated; unchanged bare-nostr insertion behavior and unrelated hardening are not blockers.

Source-only on isolated Blox: no checkout, installs, builds or tests executed. Existing exact-head CI 36058214700, sampled around 21:07Z, had no failures but two browser shards unfinished; that is a snapshot, not a final CI result. GitHub reports merge conflicts. Conflict resolution/current integrated-head CI, native/live-relay acceptance, process-restart outbox recovery and real-browser media-delete focus remain unverified. This is not release certification.

Comment thread src/features/messages/MessageComposer.tsx
Comment thread src/features/messages/MessageManagement.tsx Outdated
Comment thread src/bundled/mentions/MentionCompletion.tsx
Keep exact session edit rows authoritative, expose manual message unread intent to the menu, and exclude completed mention links from completion recovery. Preserve merged attachment provenance and persistent sidebar behavior.

Co-authored-by: Princess Donut <f0d7f043ab0904a57f19ea7215f4cd1a50ee2798a07f509eb4e9ecd275e2fe51@buzz.block.builderlab.xyz>

Co-authored-by: Mongo <b07265ca2fbc3aca5c5a02ac4c5bb4532101401eaf44a591e995581c8cb167d8@buzz.block.builderlab.xyz>
Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>

@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 re-review clear: the three prior P2 findings are fixed; no additional blocking defect found in the changed integration. Exact-session editing now reads the exact owner’s current row with abort/staleness guards; own-message manual unread is reversible without entering notification counts; completed bound-mention links no longer capture Enter through recovery completion. Matching regression coverage is present.

Reviewed 087114e8434750cf1f5cf74a59d641e59ab4ceb4 against pinned base 119195ea331de33c8480bab180df0091ca8e9421, focusing on the prior findings and main integration across channel/DM, session, thread and media-review ownership. Current-source/attachment provenance, no-change edits and deletion recovery remain intact in the reviewed paths. An independently challenged retained-window concern was rejected: retained rows remain ready with cached freshness.

Existing exact-head CI 36068134467 passed, including JavaScript/Rust and Chromium/WebKit journeys, on synthetic merge 3782580 with the pinned base. GitHub currently reports conflicts with main; that green run does not validate a resolved current-main merge. Windows native validation was skipped.

Source-only review on isolated Blox; no PR code, builds or tests executed by this review. Native GUI/live-relay acceptance, process-restart outbox recovery, real-browser media-delete focus and live uploaded-media editing remain unverified. Conflict resolution and CI for the resulting head remain delivery gates. This is a COMMENT, not approval or release certification.

Carl added 2 commits September 24, 2026 19:39
Preserve message subtree reads alongside conversation-wide read actions. Clear saved message-force hints atomically with channel reads, release active forces only after persistence, and serialize later message intent. Retain both incoming and existing regression coverage.

Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>
Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>

@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 ordering regression, detailed inline. Preserve the last explicit channel-unread intent across pending message/channel saves and add a deterministic held-storage regression.

Reviewed fb5b3e606fb7db2cec278636035904e74a04c602 against pinned base df7b7e7f45739f3e06e12d81623385701acdc51d, integrating prior message-management evidence with the merge delta and independently checking the surviving read-state race. Scope includes channel/DM/thread/session/media edit and deletion ownership, mention preservation, and device-local read controls. The merged workflow feature is already in the current base, not a new PR189 finding.

Source-only on isolated Blox; no PR code or tests executed by this review. Existing integrated-head CI 36088413941, sampled at 03:04–03:05Z, passed JavaScript (3,747 tests in 344 files), browser measurements (7/7), security checks and DCO. Four browser-journey shards and Rust/tool integration were unfinished; Windows native validation was skipped. Final CI, native/live-relay acceptance, process-restart recovery and real-browser media-delete focus remain unverified. This is not release certification.

Comment thread src/features/relay/unread.ts
Signed-off-by: Carl <c217fe6b9d958f41c3a5e030dccc7f626775a923089cb6491305eade75ea1f1b@buzz.block.builderlab.xyz>

@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 re-review clear: the prior P2 explicit-intent ordering defect is fixed; no additional blocking defect found in the two-file correction. Local unread, local clear, and explicit mark-through now share the existing channel queue with message/channel actions. Invocation-time evidence and transaction-time access checks remain intact. The nine added held-storage cases exercise both intent orders and invalidation. One non-blocking test-cleanup suggestion is inline.

Reviewed e778f488f0146bc7d36bae985044f4a3a28e6175 against prior reviewed head fb5b3e606fb7db2cec278636035904e74a04c602, with pinned base df7b7e7f45739f3e06e12d81623385701acdc51d. Existing edit/delete/session/mention/attachment contracts are unchanged by this correction. Source-only on isolated Blox; no PR code or tests executed by this review.

Existing exact-head CI 36089774667 passed on merge a48316c with that base: 3,756 unit tests, 664 Chromium/WebKit cases, Rust/tool integration, and browser measurements. No tests were removed from the correction. GitHub currently reports no merge conflicts; required review remains a separate gate. Windows validation was skipped. Native/live-relay acceptance, process-restart recovery, and real-browser media-delete focus remain unverified. This is a COMMENT, not approval or release certification.

h.emit([roster(h.relay, "room", [], 20)]);
h.grant("room", 21);
} else await h[action]();
held.release();

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.

Non-blocking: release the held save in finally

This invalidation matrix releases storage only after the lifecycle operation completes. If that operation throws, the pending read and queued mark retain an unresolved storage gate. Put the lifecycle operation in try and held.release() in finally, then await the captured results. The other new held-save cases at lines 1622 and 1649 should use the same pattern, matching the existing tests at lines 1277–1284. The ordering regression coverage itself is sound; this is failure-path cleanup, not a remaining product blocker.

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