镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Add consent-based DM-to-thread conversion - #2950

Open
lucas-rosen1 wants to merge 6 commits into
block:mainfrom
lucas-rosen1:lrosen/dm-to-thread
Open

lucas-rosen1 wants to merge 6 commits into
block:mainfrom
lucas-rosen1:lrosen/dm-to-thread

Conversation

@lucas-rosen1

@lucas-rosen1 lucas-rosen1 commented Nov 7, 2026 •

Copy link
Copy Markdown

Bring an existing private DM into a channel thread after every participant approves. The source DM remains intact; the copies preserve authors, original timestamps, current edits, attachments and reply structure.

Demo

Watch the feature walkthrough — whole and partial conversion, original timestamps and nested replies, decline/cancel, attachments, and repeat conversion. Recorded in the actual browser app with disposable accounts against a local Rust relay; this is browser evidence, not native acceptance.

Behavior

  • Channel actions → Convert to thread includes the whole DM. A main-DM message’s Convert to thread from here action includes that message and subsequent messages across the DM, including thread replies, up to the committed cutoff. Thread replies and conversion notices cannot start a conversion. The dialog displays its fixed range instead of a Messages dropdown.
  • Partial approval cards show the exact starting message, its author/time and a View message link. The signed message ID and timestamp must agree before a request or approval can be published. Unavailable boundaries block consent; later deletion preserves an already committed boundary.
  • Every human approves; verified local agents are represented by their owners. Once everyone approves, posting waits for the approving apps to be online. Public destinations add missing participants after consent; private destinations require existing membership. Each app signs only its own authors’ copies, with durable receipt recovery.
  • Images and files retain existing same-community links and effective edited attachment metadata. Copies show Originally sent in the viewer’s local time zone and preserve known reply ancestry. Deleted messages are omitted; unavailable deleted ancestry blocks copying.
  • Repeat conversions require fresh approval and create separate threads. Conversion notices are excluded in every state, including completed, declined and cancelled requests. Messages sent after conversion are not automatically copied.
  • Unavailable Request approval buttons explain their blocker on hover or keyboard focus. Shared Dialog/Menu/Button/Field/Select and BuzzLinkPreview owners supply the UI; the authorized FOUNDATION session change only filters coordination events from ordinary notifications and agent listeners.

Validation

  • Checked head: 983ad2ff63915cce88b697a36f803b289391a916, integrated with upstream 4b7188c. All mandatory commit/push gates passed: TypeScript, 563 related unit-test files with one worker (28m 38s), design types/guards, workspace Clippy and machine GitHub policy. The focused plan/consent/coordinator/dialog selection also passed all 22 tests.
  • Actual local Rust relay and two production browser clients exercised unanimous approval, partial starting-message previews, decline/cancel, nested reply copies, timestamps, attachments and repeat conversion. No destination writes preceded approval. Successful copy counts were 3, 2, 1 and 6 for whole, partial, attachment and repeat cases; declined/cancelled destinations stayed empty. Authenticated image/file reads returned the exact uploaded bytes.
  • The affected browser file exercises real menu portals, keyboard/pointer activation, navigation history/dismissal, fixed ranges, disabled explanations and exact-preview navigation. Three browser cases were added in this PR, including two in the latest follow-up; none were removed or moved from lower-layer coverage. After the upstream merge, 5/6 browser runs passed: the full dialog and reply-menu journeys passed in Chromium and WebKit, and the partial preview passed in WebKit. Chromium’s enlarged narrow preview fails the bounds check listed below. These boundaries require app/browser integration; protocol and consent scenarios remain in Vitest.
  • Earlier native IPC tests exercised production handlers with synthetic credentials and loopback TLS: custody restoration, valid signatures, identical retries, NIP-98 authentication and denied custody. Earlier capability tests allowed the main window and denied guest/remote/huddle webviews. These results precede this upstream merge and do not establish current native acceptance.

Remaining before ready

  • Fix the narrow approval-card overflow at 390px with 130% text: Chromium’s preview-link bounds check fails by approximately 4px, and the Cancel move capsule can extend outside the bubble. No assertions, timeouts or retry policies were relaxed.
  • Complete native multi-client/local-agent, OS Keychain and restart acceptance, plus human verification of the final integrated build. Hosted agents, patches and guest destinations remain unsupported.
  • Obtain required CI/DCO and code-owner review. Keep this PR draft; no readiness attestation has been added.

Implementation and acceptance steps: docs/dm-to-thread.md.

lucas-rosen1 and others added 2 commits November 7, 2026 12:20
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Lucas Rosen <lrosen@squareup.com>
Grant the main window the moved-message commands, cover native IPC custody
and receipt recovery, and resolve the destination name before approval.
Use the existing direct-reply format for copies directly under the new root.

Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Lucas Rosen <lrosen@squareup.com>
lucas-rosen1 and others added 4 commits November 7, 2026 18:03
Display an Originally sent caption on each copy, including grouped and
nested messages, using the existing local date and clock formatting.

Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Lucas Rosen <lrosen@squareup.com>
Use fixed whole-DM or message-based ranges, show the exact starting message to approvers, explain unavailable submission, retain edited attachment metadata, and exclude prior conversion notices. Reject thread replies as starting points and cover repeat consent.

Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Lucas Rosen <lrosen@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Lucas Rosen <lrosen@squareup.com>
Validate the signed starting timestamp before requests and approvals. Preserve committed scope when its starting message is subsequently deleted.

Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Lucas Rosen <lrosen@squareup.com>
@lucas-rosen1
lucas-rosen1 marked this pull request as ready for review November 9, 2026 22:37
@lucas-rosen1
lucas-rosen1 requested a review from a team as a code owner November 9, 2026 22:37
@tellaho

tellaho commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

🤖 Could we hold the DM-to-thread conversion flow until after the Nov 10 event? The new actions and consent flow add a core experience outside the current UI/UX frost. New UX follows the external-plugin policy; design can revisit the approach after the event.

This branch has not been deployed

No deployments
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