Skip to content

Spec: inline Bridge media in Channel history — reuse verified IM media #1020

Open
2 of 10 issues completed
Open

Description

@DoodleBears

Verified media versus remaining Channel presentation — 2026-10-09

Human clarified the actual acceptance in the repository orchestration chat:

Platform Human-confirmed working behavior Not established by this clarification
Personal WeChat Images, audio/voice and video verified; existing qualified intake/processing/reply work must be reused The remaining slice-specific inline Channel history/access/recovery criteria below
QQ Images, audio and video verified No new QQ media slice or blanket future-provider acceptance is created here
Lark / Feishu File behavior verified; image slice #1021 is closed Audio/video acceptance was not specified; dedicated Channel file UI PR #1077 remains open/draft
Slack File behavior verified Human has not tested images or audio; video status was not specified
Discord File behavior verified Human has not tested images or audio; video status was not specified

These are Human acceptance facts for the tested product paths, not a claim that all media is missing. Preserve them when selecting remaining work. Reuse closed WeChat #903–#907, Channel routing #909, Slack source-file #831 and Discord source-file #1002; do not reimplement those capabilities under this presentation specification.

This specification's remaining scope is inline Human Channel history presentation: media appears/plays/downloads in its original external message bubble, through current Channel/source authorization, with the stated retention/recovery behavior. Existing Bot Inbox source-details previews and checked Bot media processing are delivered prior art. This clarification did not specify a fresh runtime/Channel-history authorization/recovery matrix, so it does not by itself close the nine open presentation slices.

Source audit on current main 59ab5769: packages/core/src/messaging/channel-media.ts still restricts this Human Channel media path to images; packages/client/src/client/channel-message-body.tsx renders Bridge media through BridgeImage. The Inbox external-source details already contain audio/video controls. Dedicated Lark Channel file actions are implemented in draft PR #1077, which is not merged. Thus remaining Channel UI work must be described separately from already working native media/files.

Audio playback and transcription are separate. #1025/#1028 require actual audio/video playback/download qualification, not a new ASR service. Existing platform transcripts may be shown with provenance; absence of a transcript must not prevent supported original-audio playback. Slack provides a Generate transcript action for its native clips (official guide); this does not establish that the checked adapter receives that transcript. Discord's public voice-message contract exposes the audio attachment, duration and waveform, without a transcript field (official contract); qualify the actual media path rather than assuming a transcript.

Existing native parents, blockers, claims and acceptance criteria stay in force. This reconciliation creates no new implementation claim, receiver takeover, platform operation or merge authorization.

Problem Statement

Human users cannot inspect external Bridge media naturally in Channel history. Bridge messages project text and origin, while existing local attachments and external source-details previews use separate paths. Images, voice/audio, files and video may be reduced to text placeholders or require opening source details. Provider-specific fields, multiple attachments, authorization and retained history are not a complete cross-platform presentation contract.

Solution

Render media inside the originating Bridge message bubble, preserving the external message boundary, content order where known, and the source-name button above the bubble that opens source details. Support WeChat, Lark/Feishu, Slack and Discord through individually qualified capabilities; future providers must implement the same extensible presentation contract. Unsupported native capabilities and playback formats have truthful fallbacks rather than fabricated content.

This specification changes Human presentation only. It does not change Bot understanding, model-context assembly, explicit reading, Inbox admission, wake behavior or external sending authority.

User Stories

  1. As a Human Channel participant, I want Bridge media in the message bubble so that I can understand the conversation without opening source details for each message.
  2. As a Human, I want the external source name to remain visible and clickable so that I can inspect provenance.
  3. As a Human, I want external authors to retain their identity so that media does not appear to be authored by a local Human or PersonaBot.
  4. As a Human, I want text and multiple media items to retain one message boundary so that an album or mixed message does not become fabricated separate messages.
  5. As a Human, I want known native ordering preserved so that text and media retain their relationship.
  6. As a Human, I want unknown ordering represented honestly so that the UI does not invent source structure.
  7. As a Human, I want visible images to load automatically so that image messages are directly readable.
  8. As a Human, I want to enlarge an image so that I can inspect its details.
  9. As a Human, I want loading, failure and retry states so that an unavailable image is distinguishable from an empty message.
  10. As a Human, I want voice/audio prepared after I choose playback so that messages do not play automatically.
  11. As a Human, I want a bubble-local audio player and known duration so that I can listen without leaving the conversation.
  12. As a Human, I want existing platform transcripts identified as platform content so that I understand their origin.
  13. As a Human, I want audio without a transcript to remain playable when supported so that missing transcription does not hide the recording.
  14. As a Human, I want the original audio download so that converted playback does not replace the received recording.
  15. As a Human, I want video playback in the bubble after an explicit click so that I can inspect video messages without autoplay.
  16. As a Human, I want a real qualified video poster when available so that no generated image masquerades as a native thumbnail.
  17. As a Human, I want original video download and an honest unsupported-format fallback so that playback limitations do not misrepresent media availability.
  18. As a Human, I want file cards with name, known type and known size so that I can identify received files.
  19. As a Human, I want downloads and the existing safe open-with experience where available so that I can use received files on the applicable device.
  20. As a Human, I want files never opened automatically or written back to the provider so that viewing is not an external modification.
  21. As a Human, I want images, audio, files and video supported across current Bridge platforms so that provider differences do not prevent a coherent local conversation.
  22. As a Human, I want actual platform limitations stated so that unavailable operations do not appear functional.
  23. As a Human, I want future providers to use the same presentation contract so that another integration does not require a separate media UI.
  24. As a Human, I want Channel access to include its authorized Bridge media without choosing a Bot identity so that shared viewing is natural.
  25. As a PersonaBot, I want Human viewing to leave my reading and sending authority unchanged so that shared presentation does not borrow my identity.
  26. As a PersonaBot, I want Human previews not to count as Observation or wake me so that media rendering does not change attention semantics.
  27. As a Human, I want Inbox-only sources to remain outside Channel history so that presentation does not change routing.
  28. As a Human, I want refresh and Host restart to preserve media history so that the feature works beyond one live receipt.
  29. As a Human, I want already acquired media retained after ordinary Bridge reception is stopped so that disabling future intake does not erase history.
  30. As a Human, I want unbinding or revoking media access to stop new acquisition and serving through that authorization so that retained bytes cannot bypass revocation.
  31. As a Human, I want independent authorized reception paths evaluated separately so that revoking one path does not revoke an unrelated valid path.
  32. As a Human, I want Content Purge to use the canonical purge rules so that retained media cannot resurrect purged content.
  33. As a Human, I want bounded acquisition and explicit over-limit states so that large media does not bypass Host limits.
  34. As a Human, I want truthful per-platform verification and real UI evidence so that claimed support matches delivered behavior.

Implementation Decisions

  1. Authority. Source Event owns canonical message content and trusted provenance. Channel placement and Bot Inbox admission reference it. Media references must not create a second authoritative message store. Reuse the existing Host-managed Attachment owner for acquired bytes and approved playback derivatives. External provider URLs, tokens, AES keys and credential material remain Provider-private and do not enter Client data or public diagnostics.
  2. Platform contract. Provide an extensible non-secret presentation description of ordered media items, optional native duration/transcript/poster and actual operations. Distinguish declared capability, current authorization, available bytes and playable format. Qualify each current provider separately. Support native multiple attachments and mixed content without changing Bot understanding or promising that the model consumes additional media. Do not infer type from arbitrary text or synthesize trusted resources from URLs in message prose.
  3. Projection. Both realtime Channel delivery and historical Channel reads project the same canonical media references. Preserve one native message boundary. Keep the source-name button and source-details Modal; inline media does not replace provenance inspection. Inbox-only events create no implicit Channel placement.
  4. Images. Acquire previews when the message enters the visible viewport. Click enlarges the image. Bound loading and concurrency; provide loading, error and retry states, and cancel obsolete work on navigation/disposal. Validate content types before embedding. An inaccessible source never falls back to a raw provider URL.
  5. Audio. Explicit click prepares and plays a supported recording in the bubble. No autoplay. Show duration only when known; show existing platform transcription with its origin and preserve meaningful no-transcript state. Retain original download. Reuse qualified WeChat original-voice and bounded playback preparation rather than introducing another conversion lifecycle. Do not add model transcription or arbitrary transcoding capabilities.
  6. Video. Explicit click prepares supported video playback. Use only an actual qualified poster when available. Unsupported browser format, unavailable provider bytes and missing poster are distinct conditions. Preserve original download subject to authorization and limits. Arbitrary codec conversion, generated posters and a universal file-preview suite are outside this specification.
  7. Files. Show known name, type and size; unknown metadata stays unknown. Offer download and safe existing open-with behavior when applicable. Open-with preserves existing Host/device availability and file-opening controls. Do not automatically execute files, introduce a new application launcher or write edits back to the external provider. Viewing original external media and explicitly creating an editable working copy retain their existing distinction.
  8. Human access. Human Channel visibility permits viewing media received through an authorized Bridge. A Host-owned application-defined Service resolves trusted source and reception authorization without asking the browser to choose a Bot/account or lending one Bot's authority to another. Recheck Channel access, canonical placement, Source Event/media identity, account identity and applicable media authorization before and during acquisition and serving. Bot reads and sends continue to require that Bot's own existing authority. Human inspection is not Bot Observation.
  9. Retention and revocation. Acquisition is on demand: visible-image preview or explicit playback/file action. Reuse acquired Host files for historical reopening, with current access checks. Ordinary reception switch-off retains already acquired viewing but permits no new provider acquisition through the stopped path. Unbinding the source identity or revoking media permission denies acquisition and serving through that authorization, including already acquired bytes. Evaluate independent valid reception paths separately without substituting an unauthorized account. Metadata and message history remain; Content Purge removes content according to the canonical reference-aware purge contract. Copies already downloaded to user devices cannot be recalled.
  10. Bounds and recovery. Keep the existing default 25 MiB attachment limit, bounded transfer time and cancellation. Explicitly configured larger limits require dedicated support; never silently bypass limits for video. Cover corrupt media, expired resources, permission loss, unsupported formats, oversized content, interrupted acquisition and retry without duplicate canonical messages or unbounded downloads. Do not claim an uncached expired resource remains recoverable.
  11. Host/Client seam. Use the owning Messaging/Attachment Services and the existing authenticated Host/Client API Gateway seam. Do not add a competing interceptor, IM receiver, standalone provider Session or second media-message authority. Client presentation uses existing DSH tokens/primitives, accessibility and lifecycle conventions.
  12. Delivery. Deliver narrow, production-shaped vertical slices through provider normalization, canonical Source Event, Channel projection, authorized Host media access and operable Client UI. Each issue gets one PR and real acceptance evidence, then waits for Human QA before expanding dependent work. This spec authorizes planning; it does not start implementation, merge, deploy or take ownership of another task's receiver.

Testing Decisions

  • Human confirmed the highest acceptance seam: a real provider message enters an explicitly configured Channel, renders/previews/plays/downloads in the bubble, survives refresh and Host restart, and has observable stop/revoke/failure-recovery behavior.
  • Test external behavior through existing Messaging, Channel-query, attachment-access and Client seams rather than implementation structure. Cover both realtime delivery and historical reload, multi-item boundaries/order, trusted media identity, current access checks, interrupted transfer and retry.
  • Verify no second Source Event or duplicate Channel message appears, Inbox-only remains outside Channel history, and Human viewing changes no Bot Observation, admission, model context, wake or external-send authority.
  • Test cross-Channel/source/media identifier substitution, account changes, membership removal, switch-off, unbind, revocation during transfer/serving, independent valid paths, restart and Content Purge compatibility. Do not weaken existing own-Bot boundaries to make tests pass.
  • Existing Channel projection, canonical Source Event, external attachment access, source-details preview, file-open and original-voice preparation tests are prior art. Tests with synthetic provider payloads establish contract behavior but do not qualify real platform capability.
  • Qualify every current provider/media combination with real supported native messages. Distinguish playable, downloadable, unsupported-by-provider, unsupported-format and unverified. Platform claims require the relevant real evidence; a capability flag or successful HTTP response is insufficient.
  • Visible UI PRs require GitHub-renderable matched before/after light/dark screenshots and recordings for playback and recovery, plus applicable keyboard/accessible-control checks. Preserve privacy and secrets in evidence.

Out of Scope

  • Changes to Bot media understanding, model transcription/OCR, model-context assembly, attention or external-send policy.
  • Automatic replies, media forwarding, new native video-reply capability, subscriptions, receiver takeover or a second source store.
  • Arbitrary media URLs, direct Client access to provider credentials, borrowed Bot identities, permission bypass or silently expanded provider scopes.
  • Autoplay, generated transcripts/posters, universal document previews, arbitrary codec conversion, automatic execution or external file write-back.
  • Unbounded downloads, silently raised limits, background download of all history or recovery promises for unavailable uncached provider resources.
  • Content Purge redesign, remote deletion of already downloaded user-device copies, merge or Production deployment.

Further Notes

Activity

  1. added
    ready-for-agentFully specified, ready for an AFK agent
    area:fullstackEnd-to-end Host and Client implementation
    feature:channelChannel chat, timeline, composer, and navigation
    feature:messagingMessaging module and external providers
    scope:hubParent coordination map or epic; not a standalone implementation slice
    scope:specNormative specification for follow-on slices
    on Oct 6, 2026
  2. added this to the v1.2 milestone on Oct 6, 2026
  3. DoodleBears commented on Oct 6, 2026

    @DoodleBears
    ContributorAuthor

    Portable progress checkpoint — 2026-10-07 JST

    Human requested GitHub synchronization for continuation on another computer.

    Slice Current state GitHub evidence
    #1021 — Lark images Merged, no deployment PR #1056; merge 1ff0291aac220469694aac3d54feca19a9189b62
    #1022 — Lark file cards Implemented; draft PR / exact-head CI pending / Human QA pending PR #1077; pushed head c9ce779cd527c619b9762b3117e23a50fa018daa
    Dependent media slices Not started by this task Keep the spec's issue blockers and one-issue/one-PR sequence; inspect current claims before selection

    Continue from the detailed #1022 cross-computer handoff. It contains both repository branches and exact SHAs, Provider runtime digest, install/start commands, real file checksum and UI evidence, local checks versus unresolved default-timeout/CI results, current authorization boundaries and remaining work.

    The original computer's exclusively owned Lark QA receiver PID 44299 / port 32721 is stopped, and port absence was verified. Original identity is enabled/not revoked and the mentions-only connector is restored enabled (revision 9). Another computer may establish the same authorized QA app through normal setup after checking no other task restarted it. No Profile database, credentials, local login URL or private Lark sidebar is in GitHub. A fresh machine must create its own isolated Profile; the old localhost link will not work there.

    This task's claim is handed off/inactive and the formal goal remains paused, not complete. #1022 PR includes uploaded matched light/dark UI evidence and validated PR Lens diagram; finishing exact-head checks/review/Human QA is the next step. No new merge, release or deployment is implied by this checkpoint. Existing #1070 names/@ work and WeChat #902/#909/#907 remain separate tasks and must not be silently taken over.

  4. changed the title [-]Spec: authorized Bridge media in Channel history across current and future providers[/-] [+]Spec: inline Bridge media in Channel history — reuse verified IM media[/+] on Oct 9, 2026
  5. DoodleBears commented on Oct 9, 2026

    @DoodleBears
    ContributorAuthor

    Human media acceptance reconciliation — 2026-10-09 (Asia/Tokyo)

    Human confirmed WeChat and QQ images/audio/video already work, and file behavior has been verified on the other platforms. Slack/Discord images and audio have not been tested; their video acceptance was not specified. This is direct Human acceptance, not a fresh agent platform test.

    Updated this specification's top-level status and title to distinguish remaining inline Channel history presentation from delivered media intake/processing/reply and Inbox source-details previews. Reuse #903–#907/#909, #831 and #1002. Current main 59ab5769 retains an image-only Human Channel media path; Lark file UI candidate #1077 remains open/draft. No blanket closure, duplicate implementation or takeover of its existing task occurred.

    Playback is independently useful without transcription. #1025/#1028 do not require adding ASR. Slack's native clips have a Generate transcript action; whether the checked adapter exposes it remains unqualified. Discord's documented voice-message attachment contract provides audio/duration/waveform, without a transcript field. Primary links and the exact remaining scope are recorded in the updated body.

  6. modified the milestones: v1.2, v1.3 on Oct 11, 2026
  7. modified the milestones: v1.3, v2.0 on Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:fullstackEnd-to-end Host and Client implementationfeature:channelChannel chat, timeline, composer, and navigationfeature:messagingMessaging module and external providersready-for-agentFully specified, ready for an AFK agentscope:hubParent coordination map or epic; not a standalone implementation slicescope:specNormative specification for follow-on slices

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions