# Principles

- Client diversity is a key design principle.
  - Official client list, with good UX and explanation.
    - TODO: create a feature baseline
  - Official UX guidelines for consistency.
    - Difference between protocol and clients is emphasized.
- All clients should be full-featured.
  - This also encourages client diversity.
  - Users can expect consistent experience.
    - Encourages them to try other clients, maybe use multiple at the same time on different devices.
    - Ensure that the recipient sees the messages in the same way as the sender.
  - Features should be easy to implement.
  - Lift as much work as possible to the server, clients should need the least amount of logic.
    - State management is done on the server.
  - Not wasting development resources on interoperability between a client that supports the feature and one that does not.
  - SDKs should provide very good info, so LLM helpers can be used with best efficiency.
- No flagship instance.
  - Truly decentralized.
  - Avoids wasting resources of the core developers on server maintenance.
- True decentralization.
  - Official server list, with good UX and explanation.
    - Paid hosting providers too.
  - Richer branding for servers.
- From a UX perspective, a messaging server is not just a parameter, it's a place to belong.
  - Richer branding options.
  - Mandatory web-based presence.
    - TODO: is it mandatory or should be recommended instead?
    - If someone wants to have an entirely different web page, create a subdomain.
  - In Matrix, the only way the user interacts with their server is that they have to specify the server domain name at login. No branding, no other forms that help the user remember it.
- Designed explicitly for friends & family, and small communities.
  - Maybe small companies can use it if they like the features.
  - Not designed for large-scale deployment.
- Easy server hosting.
  - TODO: investigate ways to run a server without a domain name
  - Provide a complete OS, not just Docker.
  - Zero maintenance required:
    - space is managed correctly, never run out of space
    - TODO: collect other possible problems
- Easy migration between servers (both accounts and rooms).
- No backwards compatibility.
  - Both server admins and client users are expected to update in a timely manner.
  - Most features present from day one.
- Less-featureful clients have to be correctly indicated to chat partners.
  - e.g. “Your partner has no devices that could display this message type.”
  - No interoperability or (hidden) graceful degradation hacks. No need to guess how the recipient sees your message. It either fully works, or the sender can see that it won't work at all.
- Canonical DMs.
- Easy key sharing in-app.
- Nobody cares about key verification, not even power users.
  - Implement mechanisms to avoid MITM without key verification.
- Encryption is mandatory in non-public rooms.

Some ideas to develop later:
- import conversations from other platforms and continue the chat here
  - users could import their own messages, similar to double puppeting
    - maybe not import but authorize (sign) if correct, and their account becomes associated with it
    - how do we know who 
  - difference from bridging
    - the import is a one-time action, it does not remain connected
    - control is wholly in the room, no remote
  - maybe reuse some of the bridge metadata format
- no-motion mode
  - servers can downsample animated images
- per-room data residency tag
  - rooms refuse to accept servers with different settings
    - clients must clearly show this
  - can not reimport to servers when account migrated
  - e.g. ["EU", "DE", "FR"]
  - maybe only compliance (["GDPR"]), or both region and GDPR?
    - does compliance imply every server that is compliant or only servers that reside in the given regions where the legislation is in effect?
- search keywords for rooms/spaces
- unlinkable invites to avoid exposing social graph, but still allow only trusted users
  - maybe anti-spam only, not the examct invite
  - verification system could be used somehow?
- translation
  - should document the translated version(s) at the time of the chat, so if a weaker LLM introduced translation errors that caused confusion in the conversation, it's apparent
  - clients SHOULD feed the last `n` messages from the conversation to provide context for more accuracy
  - before sending, clients SHOULD ask the sender for ambigously translatable phrases, explaining the differences
  - some rooms may provide their own translation services
    - able to restrict to only allow those (e.g. privacy management)
    - maybe use other too if allowed (e.g. when someone has expensive DeepL subscription and provides it in the given community only, but someone might have a better local model)
- location-based discovery
  - enable other users discovering you by location
  - enumeration-based attack vectors?
  - should be restricted to room/space members, e.g. you must share at least one room in common? maybe client should enable only for certain rooms?
  - must not reveal the actual location (however, it's difficult since servers know it, and anyone can run their server)
  - this was discontinued by Telegram due to abuse, so no exact copy
  - maybe provide a geofence for rooms, and the client automatically leaves it when leaving the area? or just sets the presence data for the room as "offline"?
- “opening hours” for rooms
  - useful for stuff like live chat rooms for conferences, cafés
  - can not send messages outside of the time window
- limited-time passes for rooms
  - expiring room membership
  - can be used for physical presence-based chatting, e.g. client periodically refetching a token from WiFi LAN server or BLE
    - can be abused by leaving a small device there
- fast indexing
  - allow downloading in bigger batches than in Matrix
  - events are grouped, so do not use pagination windows, but the hierarchy size
- no fallback for message content
  - non-techie users are extremely confused
    - they may not indicate that it's not working
    - it's better to deny and indicate to use other client
  - clients can easily implement their own fallbacks
    - authors may notice that after a fallback, a proper implementation wouldn't be too hard
    - standardise how fallback must be presented (e.g. “multiparty voice calls are not supported”)
    - SDKs can provide a fallback mechanism for features that they support but the client doesn't
  - outdated clients must not be used
    - protocol version is increased for every content change
  - most features will be present from v1.0
- paid plan on homeserver
  - larger retention period
  - larger media storage
  - better call resolution
  - must be able to migrate if the pricing changes
  - may be paid by someone else (e.g. organization or family)
    - appropriately show the subscription info in the client
- maybe allow more control of HS to UI?
  - matrix.to style links: homeserver.domain/user
    - difficulty to use when HS has web too
      - maybe only a subdomain for this but not for the username, if there is a username too?
- email compatibility
  - threads
  - email address shows up in conversation list
  - if they register, their profile is replaced, and conversations imported
- server instance chooser
  - high quality, officially maintained
  - no flagship server instance in order to be truly decentralized
  - support opening it from client registration flow
- client chooser
  - high quality, officially maintained
    - good UX research necessary
  - not only present a list, but add a “choose wizard” that asks simple questions
  - flagship client should not be distinguished
  - if a client not recommended, still include it but indicate the reason
- estimated response time
- auto-reply to DMs (even if no clients are online) is useful?
  - can be replaced with rich status?
- community management tools
- “knock” forms: questionnaire for users who want to join a room
  - maybe a link, similar to the anti-spam token
  - external link can help concentrate the data on only one server
    - irrelevant if it can be solved in an encrypted way?
    - however, messaging server hides ip addr in a reliable, standardized way
- room management bot for communities
  - easily associate authorized bots, to avoid scammers sending fake authorization requests for newcomers
  - use cases
    - allow message sending only after authentication
      - can be solved with restricted threads grouped under a “new user authentication” parent thread
        - it may need to be encrypted, but currently it seems that encrypted threads are unlikely to be supported in public rooms
- live streamed video
  - few seconds delay can be expected
  - „stage” streams where the clients MAY overlay the chat to the video feed
    - may require dedicated thread?
    - Q&A: moderators may select messages to show
      - maybe tagging and filtering is sufficient?
- “privacy” mode
  - limit metadata exposure when possible with technical settings
  - prominent UI warnings and education
- “noob” mode
  - similar to stranger mode, but it limits features mostly related to technical scamming
    - 3rd party webhook API authentication requests
    - key export
    - more prominent warnings when leaving to an external app/site
      - warn about possible IP address exposure
    - TODO: more
    - bot-provided buttons
- “vulnerable personality” mode
  - should be client side entirely, too sensitive
  - check messages for deception or abuse patterns or harmful conversations
  - content filters all default to the strictest UI hiding, some can not be unhidden
- webhooks
  - easy authentication, don't copy API keys around
- activity analytics
  - available to space admins
  - users can view their own
  - can be scraped with advanced tools, so there is no point in disabling it
  - only derived from the stored data, not the deleted history
- stories
  - TODO: see https://telegram.org/tour/stories
- take ideas from Circles (a specialized Matrix client)
- clear info about limits
  - max group size
  - attachment quotas, max file sizes
- query server info for easily viewing in the client
  - website
  - server admin(s) alternative contacts
  - hosting provider name, website
  - firewall info (e.g. Cloudflare)
    - whether it's 3rd party or in-house
  - description
    - summary
    - longer
  - registration openness
  - server creation date maybe
  - community guidelines (maybe also accessible from web? could provide a rendered HTML version)
  - last seen (for federated)
  - logo, cover images
  - color scheme? (or at least a primary color)
  - uptime
  - ping
  - location
    - country of physical location
    - jurisdiction(s)
  - maximum retention time
  - compliance info (GDPR, etc)
  - power source (solar, hydro)
  - donation URLs
  - documents
    - privacy policy
    - terms of service
    - community guidelines
  - attachment size and storage limits
  - federation enabled?
  - list of banned/allowed federation servers
  - list of banned/allowed communities
  - list of server focus
    - e.g. mainly for local people in Berlin
    - since communities can be connected anywhere, topics should not be specified, only demographics
  - external abuse report url (if someone do not have an account here)
  - social media profiles of the server
  - any external link (each with a label)
  - maybe separate info meant for user/admin 
  - notes (an array of random text prominently displayed)
    - maybe even at badge level? (collect use cases!)
- specify language for communities (e.g. en, fr, pt)
- user directories
  - similar to spaces, but for accounts, not chats
  - could be used to select “story” audiences
  - user discovery
  - each space could have its own
  - one user can be in multiple places in the same directory
- explore extended use cases
  - customer support
  - in-game chat
  - task management
- rich rate limiting response
  - “wait 5 minutes and try again. verify your phone number for higher rate limits”
- malware scanning
  - both at upload time on the server and download time via the client
- return rich error message if room can not be joined
  - community banned on server
    - maybe use same spamlist method -> admin creates a spam list for their server
  - it's on a spamlist that the server has enforced
  - maybe it could be solved by lazy membership, which converts room complexity to `O 1` instead of `O n`
- maybe unify the bridge, content filter, malware scanner, translator into the bot API somehow?
- auto-joined rooms must be indicated (e.g. some server autojoins users to certain rooms on registration)

## Some unstructured rambling:

Client implementation simplicity is the key. One of the main principles of this protocol is not limiting the client implementation languages. Devs should be able to write the clients in any library they want, even if there are no libraries. For example, we can't use libp2p from IPFS because there are libraries for JavaScript, Rust, and Go, and that's all. Sure, these are not so bad languages, but why not allow somebody to write some simple client for themselves in their favorite languages? Also, there are many tinkerers who like integrating technology into their lives in unconventional and personalized ways because they can tinker with it and implement their ideas in tech. For example, creating a simple e-ink display with an old Raspberry Pi, very low resources, and writing a lightweight, very lightweight client in Zig, and they don't want to consume much memory or CPU or anything. The protocol is based on HTTP, which can be very resource-hungry from the point of view of an embedded system, but if you have more than 200 megabytes of memory, then it's good. Sure, it could require kilobytes instead of megabytes, but we are good with megabytes. Even the slowest Linux phones have some megabytes available, but it should not require hundreds of megabytes for a DHT and complex routing and things like that. If an external proxy can provide it, okay, then it can be based on a DHT. Servers could use advanced technology between themselves, but clients must be very, very simple. No specific libraries. If the programming language has a JSON library and an HTTP library, it should work. It might need some bindings for cryptography, like libsodium or some other cryptographic library, but the cryptography implementation must be the only thing required for writing a basic client. Sure, if you look at the protocol, you notice that open location code is a requirement, so probably it will pull in a few hundred lines of open location code and some other nuances, but basically, in order to communicate, facilitate communication between the client and the server, an HTTP3 library and JSON decoding is what is required. Nothing else. It must be simple. HTTP3 is great. It is quick, it has non-blocking, multi-stream communication, WebTransport, many, many other great things, compression built in, quantum secure, or quantum resistant cryptography built in. It has many things, and a client can be written by standard browser APIs. It should not require state resolution and things like that, or distributed hash table or something more advanced should not be in the client. The client simplicity, implementation simplicity is key. One of the goals of the protocol is client diversity. This means that many of the clients must be fully featured. Features must not lock users to a few main clients, like in Matrix, where everyone uses Element and maybe FluffyChat, but nothing else. Even basic clients should provide enough features for chat. A developer could set up an authentication and basic message sending in an afternoon if they start reading the docs in that afternoon. So they are finding this protocol first, they start learning it, and at the start of the afternoon and in the evening, they have a working client that can send at least text messages. It must be that simple. So, client implementation must be simple. Put as much state on the server as possible.

## Technical principles

- Modern instant messaging is not sequential — it's not IRC.
  - As little connection between separate parts of the conversation as possible.
  - “event” relations must not be placed far away in a DAG with different encryption sessions.
  - Encryption should be based on the data structure, not on complex cryptographic schemes.
  - Encryption sessions and conversation parts must not be intertwined.
    - An user should be able to share a single part of a conversation with someone, without exposing other conversation parts inside the same session.
      - Share only a single thread, poll or location share.
  - Some parts of the conversation shouldn't be slowed down by another feature that generates many “events”.
    - e.g. a poll should not need to decrypt thousands of live location sharing positions in between the votes
  - Parts must be able to conveniently deleted.
    - Disappearing messages must be easy to implement.
    - Delete an entire thread, poll, or even an edited message and it should remove all related events, but nothing more.
    - Deletion must not break the room state.
    - Deletion must not break encryption.
- Data structure must make it possible to download only the necessary parts of a certain conversation.
  - download only one thread, and only the latest messages in that thread
- lessons from Matrix
  - Trying to force everything into a DAG wastes lot of resources.
  - Backwards compatibility wastes even more resources.
- Do not care about scalability and large deployments. If a solution is better for smaller deployments, but doesn't scale, use it. This protocol is meant for small rooms and communities.
- Protocol must prioritize simplifying the client implementations, even if it results in additional complexity on the server.
- SDKs should provide enough higher-level components to be able to implement a new client easily and avoid having soft forks (like SchildiChat and Element).
- Design must emphasize reducing server strain.
  - Lazy loading where possible both client-server and server-server interactions.


## Client implementation guidelines

When a client mutates something, do not rely on update propagation, proactively fetch the new data.
TODO: clarify

Some ideas for later:
- put legal hold  on 
- official client UX guidelines
- unified client terminology
- clients must send feature flags
  - e.g. when user wants to send animated sticker, it would say “your chat partner has no devices that could display this properly”
    - no devices at all, or no online devices?
  - read markers should indicate whether the message type is supported or not
- multi-account support in every client
- Cloudflare-like “global-kill” for every feature
- redact faces in photos
- federation sending errors must be clearly visible in the client (can't send because other server is unresponsive)

## Server implementation guidelines

Server implementations MUST be designed for no-maintenance.
- No "getting stuck" due to too weak CPU/RAM/etc.
  - Return errors instead of getting stuck and slowed down.
- No running out of storage.
  - Cleverly delete redundant data and later non-redundant too.
    - TODO: Avoid attacks that overload the storage to delete important data.
- maybe allow hosting for multiple virtualhosts?
  - can spare costs
    - storage
    - CPU/RAM
      - not running multiple processes
      - no federation sending overhead between 
        - maybe allow batching between virtualhosts to servers hosted elsewhere?
    - reduce latency between virtualhosts hosted on the same machine
  - needs to solve the problem of sharding out when one server gets too big
    - or simply constrain the server and notify the owner **before** they register it at the hosting provider
  - API to easily query info about virtualhots, for privacy management info?
    - could be used with DNS queries too? maybe not, if behind reverse proxy

# Error resilience

client crashes, so one interaction (e.g. result of a request) is lost

# Challenges

How do users remember which servers did they choose?

Some ideas:
- registration confirmation email
  - should not be cringe
  - must not send it immediately as this complicates onboarding
    - allow incoming invitations, but require confirmation for outgoing
      - communicate this to the client
        - simple error message?
        - maybe an account status
        - a requestable capability maybe? (it's meant for other use cases)

---
figure out some more info to include in the server info endpoint