more reorg

This commit is contained in:
a 2023-04-06 01:44:39 -05:00
parent 78a8a0afa8
commit fcb1d6818b
36 changed files with 326 additions and 407 deletions

View File

@ -1,32 +0,0 @@
+++
+++
# ActivityPub
## HTTP verbs
GET and POST/PUT/DELETE[^1] json docs? maybe some validation? needs some basic authentication too i guess
~~uri schema is handled by the client, not the server (client PUT).~~ activitypub section 6 says client should POST either an activity or an object to /outbox and then the server returns the `id` value. Server decides id, client does NOT get to decide what id is. it only gets to decide `url`.
## authorization
maybe need a token or capability to obtain read/write privs to given directories or objects? need to look into how to generate and revoke captokens and how to expose that info to clients through a standardized endpoint... OAuth? an admin token could manage and revoke which tokens have access to read/write to certain resources, maybe? but there would have to be a way of linking tokens to people or device names somehow for it to be human-meaningful...
the real issue is that i need to figure out how to create and manage actors. we can say that the oauth flow can request scopes as paths e.g. `"scope": [{"/": "rw"}]` for full access to all paths (or something like that)... but ugh idk. maybe be lazy and fallback to POSIX filesystem ACL? what that indicates is that the server will have to do its own access control but idk how. i need to figure out how.
## how to create and manage actors?
xmpp i would do like `prosodyctl adduser JID` and `prosodyctl passwd JID` so you could have a cli tool to generate read-write tokens maybe? idk. that kind of out-of-band token generation seems a bit complicated but it might be necessary if we don't want usernames to be canonical. maybe some config file could work? really lost here...
## spitballing about c2s
if the defined actor flow is as follows:
1. ask for actor
1. discover outbox endpoint
1. POST to outbox
1. server will assign id and return it to client with 201 + Location header
then idk what that means for my plans with id/url distinction... i think it means that clients have to save the id internally if they want to refer to objects later, for example. if a client POSTs an Object and it gets wrapped with a Create and then both ids are assigned... did the client get to decide the URL? and how does the server know if the URL is allowed? presumably then, we have two different levels of authorization to deal with -- one for the actor namespace (but this can be handled by the server tbh), and then another for where the client can serve? or... maybe this means that the client and server ideally should be running on different sub/domains as i suspected! **if you put the server and client on the same FQDN then there will be URL/namespace conflicts.** the server will create e.g. /actors/1/outbox and generate a corresponding OAuth token maybe. the server probably also needs to know which namespaces it actually has access to? some way to map a more human-friendly identifier to the activitypub id? can we mandate webfinger?
## footnotes
[^1] POST means the server decides the URI of the resource it receives, PUT means the client decides and the server just dumps it there

View File

@ -1,45 +0,0 @@
+++
+++
# Communication paradigms
## qualitative analysis
- deliver / fetch
- side effects (receive or relay?)
- 1-1, 1-n, n-n?
## types of communication
### Chat (n-n delivery)
- all kinds of messengers
- fixed participants/addressing
- smtp, xmpp, activitypub
### Broadcast (1-n delivery/fetch)
- feeds/social
- make a resource available to audience
- actitypub (when not @ anyone), rss, atom
- xmpp status updates / PEP, "stories" (loosely)
### Wall/Forum (1-n relay/fetch)
- Facebook profile/group page, bulletin board forums
- loosely organized by page
- activitypub only? which vocab to use? what type of actor? how to follow a thread? needs extensions...
### Room (n-n relay)
- IRC and its various clones, mailing lists, etc
- irc channel, smtp mailing list, xmpp muc, activitypub Service actor?
## What do i actually use tho
- read (feeds -- rss, atom, activitypub?)
- publish (broadcast -- but also websites/pages/etc?)
- chat (chat -- messaging over smtp/xmpp/activitypub)
- 1:1 chat
- closed group (define participants)
- deliver to all those participants, or have them fetch it from a central Service? (probably the former)
- open group (participants can join/leave at any time without approval)
- better served by room model than chat model
- delivery to all participants becomes impractical and limited, so central Service becomes more necessary to store and forward
- lurking in rooms?
- kind of like read, but with ability to send (so a mix of read + open group?)
- rooms are actually misused imo! people turn irc channels into the equivalent of forums and it's actually the wrong paradigm entirely
- i think rooms should be created and destroyed as needed for when people need to actually have a live chat
- i'm mostly fine with offloading this to jitsi i guess? no pressing reason to implement my own stuff for this, and also jitsi provides voice/video chat and screensharing at the same time so it's probably way better than anything i could ever do on my own
- perhaps by design rooms should ask the user to turn on logging? to maybe communicate that this is not a permanent place for discussion? or an option to destroy the room and convert the chatlog to a forum post? idk...

View File

@ -1,17 +0,0 @@
+++
+++
# Things you would need to do for compatibility
## Mastodon
### Unique username+domain pair
- webfinger domain.example for resource `acct:preferredUsername@domain` must link to your activitypub actor
- mastodon will do this even when given a direct activitypub actor id
- if webfinger is forwarded, mastodon will get the linked id and do the above
## Representing polls
- `Create Question` instead of just `Question` or `Create Note{attachment: Question}` (being treated like an object instead of an activity)
- Votes are `Create Note{name, inReplyTo: Note{attachment: Question}}` and the replied-to note must be local

View File

@ -1,141 +0,0 @@
+++
+++
# Ideas for extensions and differences from current implementations
## max followers
https://github.com/mastodon/mastodon/issues/20089
max followers? mastodon has a MAX_FOLLOWS and MAX_FOLLOW_RATIO so why not MAX_FOLLOWERS
## Webfinger Content-Type of activitystreams profile
i wonder if setting a Content-Type of `"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""` instead of `"application/activity+json"` would break anything
## Message type
Message is an IntransitiveActivity?
```yaml
id: https://alice.social/activities/1
actor: https://alice.social
type: Message
to: https://bob.social
content: "hello bob"
```
could also be a regular Activity, where `object` is the conversation or room?
```yaml
id: https://alice.social/activities/1
actor: https://alice.social
type: Message
object: https://alice.social/rooms/1
to: https://alice.social/rooms/1/audience
content: "hello room"
```
instead of making it transitive, we could swap `object` for `context` which is a bit more semantically correct if pointing to a collection?
```yaml
id: https://alice.social/activities/1
actor: https://alice.social
type: Message
to: https://alice.social/rooms/1/audience
content: "hello room"
context: https://alice.social/rooms/1
```
or have both `object` and `context`?
```yaml
id: https://alice.social/activities/1
actor: https://alice.social
type: Message
object: https://alice.social/rooms/1
to: https://alice.social/rooms/1/audience
content: "hello room"
context: https://alice.social/rooms/1/context
```
## distribution model
[tldr i should choose if i want my reply to go to my followers, or their followers, or just them, or all of the above, or whatever]
direct addressing should be better supported
alice makes a post and sends it to her followers or whatever. optionally it can be made available to the public?
```yaml
id: alice.example/54078934249073290847321094/activity/1
actor: alice.example
type: Create
object:
id: alice.example/54078934249073290847321094
type: Note
content: "hello world"
audience: Public # could be alice.example/followers instead
cc: [alice.example/followers, Public]
```
bob replies to alice, they send that to alice only, and *maybe* optionally to their followers. **this should be up to the user (bob).**
```yaml
id: bob.example/94378256423895476238954/activity/1
actor: bob.example
type: Create
object:
id: bob.example/94378256423895476238954
type: Note
inReplyTo: alice.example/54078934249073290847321094
content: "hi i'm bob"
audience: Public
to: [alice.example]
cc: [alice.example/followers, bob.example/followers] # alice's followers will be inbox-forwarded if alice allows it
```
alice can then choose to redistribute that reply. **this should be up to the recipient (alice)** and also **this should be made clear to the replier (bob)**
```yaml
id: alice.example/7659804769058743906/activity/1
actor: alice.example
type: Announce
object: bob.example/94378256423895476238954
cc: [alice.example/followers, bob.example]
```
note that alice might allow bob's replies to be automatically redistributed, if alice trusts bob.
bob may not want his reply to be redistributed though
```yaml
id: bob.example/15789436589346/activity/1
actor: bob.example
type: Create
object:
id: bob.example/15789436589346 # may be excluded but could be better to explicitly specify as null. if provided, will return 401 Not Authorized if you do HTTP GET
type: Note
inReplyTo: alice.example/54078934249073290847321094
content: "i'm gay. don't tell anyone"
audience: alice.example
to: [alice.example]
```
alice can reply to bob's private reply, but no one else can see that reply
bob might also make his reply explicitly anonymous and transient by using id: null or not providing id
alice's reply SHOULD NOT target her followers, although she is capable of doing so. **this should be an explicit decision.**
### maybe objects shouldn't be inlined tho
spritely magenc golem ocappub etc etc etc
```yaml
id: alice.example/54078934249073290847321094/activity/1
actor: alice.example
type: Create
object: alice.example/54078934249073290847321094 # how to fetch this?
cc: [alice.example/followers, Public]
```

View File

@ -1,7 +0,0 @@
+++
+++
## api?
- no counts/numbers unless directly relevant. example: `replies_count` integer -> `has_replies` boolean.
- follower counts can be faked

View File

@ -1,16 +0,0 @@
+++
+++
# Joke ideas for federation that are still actually kinda valid but funny
## Federated mutes
as2 has an Ignore type so you could theoretically federate out mutes in the same way that blocks are currently federated
### Block/Mute reminders
anytime someone muted tries to reply, you respond with an Ignore
anytime someone blocked tries to interact, you respond with a Block
what if you do this *every single time* they try to reply/interact

View File

@ -1,18 +0,0 @@
+++
+++
# Prior art
## email
- plain text content only, with everything else being handled by metadata and headers
- no auto quoting -- quoting should be intentional
- no signatures -- that's just extraneous. at the very least signatures should be dynamic instead of static?
- username / password can be used for actor authentication via oauth? logging into an ap client should be like logging in with google?
## irc
- relay model. you send everything to a central server and it relays it to everyone connected
## xmpp
## activitypub

View File

@ -1,29 +0,0 @@
+++
+++
# Routing table
## trwnh.com
- /.well-known/webfinger -> ???
- should map a@trwnh.com to ap.trwnh.com/users/ea9f49f6-d1cc-4b9e-a221-71f6aa617efa
- /notes, /articles, etc etc -> broadcast.trwnh.com [maybe? or do i just want to run the c2s app on the root domain? indieweb? idk]
## ap.trwnh.com
- /users
- /actors? how do i want to separate profiles from users? users should be able to have multiple profiles.
- /inboxes
- /outboxes
- i have absolutely no idea how to handle authorization beyond vaguely something oauth-ish
## chat.trwnh.com
smtp / xmpp (jsxc embedded?) / activitypub dms
## rooms.trwnh.com
irc, xmpp groups, i think it makes sense to add webrtc too. basically jitsi meet or nextcloud talk, but with persistence.
## reader.trwnh.com
rss / atom / activitypub?
## accounts.trwnh.com or id.trwnh.com
identity provider?

View File

@ -1,15 +0,0 @@
+++
+++
this is really the interface that makes pure AP servers discoverable.
problem: AP `id` can be literally anything
solution: have webfinger return the `id` based on some other "friendly" uri lookup
/.well-known/webfinger?resource=
- username? `acct:trwnh` or for masto compat `?resource=username@domain.com` or `?resource=user%40email.com@domain.com` per rfc for acct uri
- phone number? `tel:+1205578890` -- needs to be standardized/internationalized i guess, maybe also accept `sms:`
- email? `mailto:a@trwnh.com`
- xmpp? `xmpp:a@trwnh.com`
- other -- http? https? urn?

View File

@ -0,0 +1,36 @@
+++
+++
## Paradigms
### 1-1 or 1-n
### push or pull
### relaying aka intermediaries
## Separation of concerns
### Publishing
> "I want to share this with the world."
For a resource to be visible to other people, it must first be published. Typically, resources are published at a location or with a specific identifier; people who wish to view that resource can then go to that location or search for that identifier using a lookup service in order to view the resource. Most commonly, resources are published on the World Wide Web, and they are found via their uniform resource location (URL). When you type, paste, or click a link in your Web browser, your browser will make a request to fetch that resource on your behalf, and the server responsible for that resource will respond with the resource.
### Subscribing
> "I want to see the things I am interested in."
OK, so there are resources that we can access if they are published at a known location or with a known identifier. How do we know when there are new or updated resources? At the most basic level, you can manually check a resource to see if it has been updated; for example, you can check a website to see if there are any new pages. To make this manual checking process easier, publishers can generate a feed or stream of resources that can be subscribed to. When you subscribe to that feed, your feed reader will periodically check the feed for any changes; for example, a feed may be updated with the latest articles from a Web site, which your reader will then pull and show to you as an update.
### Messaging
> "I want to communicate directly with people."
In some ways, messaging can be covered by having a publisher and a subscriber on each end of a conversation, but it usually makes more sense to deliver messages to your conversational partners directly rather than having them check for new messages on their own schedule.
### Discussing
> "I want to gather in a community or around a topic."
Traditionally, this has been handled by forums, bulletin board systems, and groups.

View File

@ -48,10 +48,10 @@ updated = "2021"
- assuming public by default. no. let the user determine what they want to *opt in* to publishing, not what they want to *opt out* of having visible. by default, nothing should be known about the user.
>Copying and pasting made people look at what they shared, and think about it, at least for a moment. When the retweet button debuted, that friction diminished. Impulse superseded the at-least-minimal degree of thoughtfulness once baked into sharing. Before the retweet, Twitter was largely a convivial place. After, all hell broke loose — and spread.
> Copying and pasting made people look at what they shared, and think about it, at least for a moment. When the retweet button debuted, that friction diminished. Impulse superseded the at-least-minimal degree of thoughtfulness once baked into sharing. Before the retweet, Twitter was largely a convivial place. After, all hell broke loose — and spread.
--[The Man Who Built The Retweet: “We Handed A Loaded Weapon To 4-Year-Olds”](https://www.buzzfeednews.com/article/alexkantrowitz/how-the-retweet-ruined-the-internet)
>[S]ocial media has been overtaken by metrics, which are driven in large part by the vicious cycle of advertisers wanting to know which influencers are worth paying; and by toxic fan battles to make your favorite social media accounts gain followers and likes, and to downrank your favorites' rivals.
> [S]ocial media has been overtaken by metrics, which are driven in large part by the vicious cycle of advertisers wanting to know which influencers are worth paying; and by toxic fan battles to make your favorite social media accounts gain followers and likes, and to downrank your favorites' rivals.
--[Demetrification: improving social media by removing public like/follower/repost counts](https://boingboing.net/2019/09/12/flickrs-glory-days.html)

View File

@ -1,85 +0,0 @@
+++
+++
# Gotchas
{{<toc>}}
## DO NOT VALIDATE @CONTEXT IF YOU DO NOT UNDERSTAND JSON-LD
you CANNOT check for the presence of `https://www.w3.org/ns/activitystreams` AT ALL -- the activitystreams context may be included within another context hosted elsewhere. just ignore this property entirely if you don't understand it
## DON'T BE STRICT ABOUT VALIDATING ID
do NOT try to be overly strict about dereferencing IDs. some IDs may not be on your domain, or otherwise they may not be present at all, or they may be explicitly null. null or missing id indicates a transient activity.
### example: Follow semantics
Follows are realistically transient. it is therefore enough to:
- keep track of local state
- mutate state based on activities
if you receive an Accept/Reject Follow, check ONLY for the following:
- actor
- type == Accept/Reject
- object.actor
- object.type == Follow
- object.object == actor
if object is inlined, you don't need to check that object.id is local. the above is enough information, PROVIDED THAT you have a local pending follow request. if you do not have a pending follow, then DO NOT process an incoming Accept Follow. however, you may receive a Reject Follow at any time, indicating that you should destroy that follow relationship. note that you may also receive an Undo Accept Follow by some implementations. this is discouraged but should be handled as well
<https://github.com/misskey-dev/misskey/issues/9250>
## DO NOT CHECK TYPES DURING VALIDATION
an Actor has an `inbox` and `outbox`. that's it.
an Activity has an `actor`. that's it.
a Collection has `items` or `orderedItems`. that's it.
etc
## DON'T PANIC WHEN YOU SEE A TYPE YOU DON'T UNDERSTAND
say you understand tags of type Mention and Hashtag and Emoji. someone sends you a `tag` array with a raw Link. DON'T PANIC. the document is still valid. just filter out anything you don't understand, something like
```python
UNDERSTOOD_TAG_TYPES = set("Mention", "Hashtag", "Emoji")
document = json.loads(...)
tags = document.get('tag', [])
tags = [
tag
for tag in tags
if tag['type'] in UNDERSTOOD_TAG_TYPES
]
# do whatever you need to now
```
```javascript
const UNDERSTOOD_TAG_TYPES = new Set(["Mention", "Hashtag", "Emoji"])
let document = ...
tags = document.tag.filter(tag => tag.type in UNDERSTOOD_TAG_TYPES)
// do whatever you need to now
```
## DO NOT CONFUSE ITEMS AND ORDEREDITEMS
`items` indicates that this is a Collection
however, `orderedItems` is valid on both Collection and OrderedCollection! it is defined like this in the as2 context:
```json
"orderedItems": {
"@id": "as:items",
"@type": "@id",
"@container": "@list"
}
```
so it is basically just an alias for `items` where it MUST be an array, and the array's order matters. (if it were `@container: set`, then it MUST be an array, but the array's order does not matter.)
### tangent: a Collection may be ordered without being an OrderedCollection
OrderedCollection is defined as strictly reverse chronological by ActivityPub. however, other orderings are valid on regular Collections. the use of the `orderedItems` term allows plain-JSON implementations to do exactly this.

View File

@ -0,0 +1,85 @@
### Emoji {#emoji}
See for more: <https://docs.joinmastodon.org/spec/activitypub/#emoji>
A sub-type of Link that refers to a `:custom_emoji:`, typically used for replacing a plain-text substring with an inline image (by implementations that do not otherwise support arbitrary inline images).
#### Implementation details {#emoji-implementation}
Handling an Emoji is typically done by matching for the Emoji's `name` and replacing with an `<img>` element where `src` is the `url` of the Emoji's `icon`.
<p class="callout warning">Note that this extension uses `icon` instead of `href`, but the same "search-and-replace" semantics apply, as with any microsyntax.</p>
Consider the following Note:
```json
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"toot": "http://joinmastodon.org/ns#",
"Emoji": "toot:Emoji"
}
],
"id": "https://example.com/@alice/hello-world",
"type": "Note",
"content": "<p>Hello world :kappa:</p>",
"tag": [
{
"id": "https://example.com/emoji/123",
"type": "Emoji",
"name": ":kappa:",
"icon": {
"type": "Image",
"mediaType": "image/png",
"url": "https://example.com/files/kappa.png"
}
}
]
}
```
- We extract the natural-language properties of `name`, `summary`, and `content`. In this case, we have only `content` of `Hello world :kappa:`.
- We extract any elements from `tag` with a type of `Emoji`. In this case, we have only one, for `:kappa:`.
- We search for `Emoji.name` (`:kappa:`) within the identified `content` (`Hello world :kappa:`) and replace it with an inline image sourced from `Emoji.icon.url` (`https://example.com/files/kappa.png`), resulting in the final value for content being `<p>Hello world <img src="https://example.com/files/kappa.png"/></p>`.
Pseudocode might look something like this:
```py
# Extract custom emojis from tag array
tags = Object.tag
Emojis = [tag for tag in tags where tag.type == "Emoji"]
for Emoji in Emojis:
# replace :emoji: microsyntax with an inline image (within name)
name = Object.name # may need to extract `name` from `nameMap` instead
name_matches = regex.match(substring = Emoji.name, text = name)
for match in name_matches:
search_and_replace(
text = name,
search = Emoji.name,
replace = f'<img src={Emoji.icon.url}>'
)
# replace :emoji: microsyntax with an inline image (within summary)
summary = Object.summary # may need to extract `summary` from `summaryMap` instead
summary_matches = regex.match(substring = Emoji.name, text = summary)
for match in summary_matches:
search_and_replace(
text = summary,
search = Emoji.name,
replace = f'<img src={Emoji.icon.url}>'
)
# replace :emoji: microsyntax with an inline image (within content)
content = Object.content # may need to extract `content` from `contentMap` instead
content_matches = regex.match(substring = Emoji.name, text = content)
for match in content_matches:
search_and_replace(
text = content,
search = Emoji.name,
replace = f'<img src={Emoji.icon.url}>'
)
```

View File

@ -0,0 +1,33 @@
### Hashtag {#hashtag}
A sub-type of Link that refers to a `#topic`, typically used for associating the object with a collection of other objects sharing the same topic.
#### Implementation details {#hashtag-implementation}
<p class="callout hint warning">Not officially part of the ActivityPub context definition, but still assumed to be included in the ActivityStreams `as:` namespace by most implementations (for historical reasons). Implementations should manually define `as:Hashtag` in their JSON-LD `@context`.</p>
The `href` typically links to a collection of all objects tagged with the same Hashtag.
Consider the following Note:
```json
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"Hashtag": "as:Hashtag"
}
],
"id": "https://example.com/@alice/hello-world",
"type": "Note",
"content": "<p>I am talking about a #topic</p>",
"tag": [
{
"type": "Hashtag",
"name": "#topic",
"href": "https://example.com/tagged/topic"
}
]
}
```

View File

@ -0,0 +1,2 @@
+++
+++

View File

@ -0,0 +1,2 @@
+++
+++

View File

@ -0,0 +1,21 @@
## DO NOT CONFUSE ITEMS AND ORDEREDITEMS
`items` indicates that this is a Collection
however, `orderedItems` is valid on both Collection and OrderedCollection! it is defined like this in the as2 context:
```json
{
"orderedItems": {
"@id": "as:items",
"@type": "@id",
"@container": "@list"
}
}
```
so it is basically just an alias for `items` where it MUST be an array, and the array's order matters. (if it were `@container: set`, then it MUST be an array, but the array's order does not matter.)
### tangent: a Collection may be ordered without being an OrderedCollection
OrderedCollection is defined as strictly reverse chronological by ActivityPub. however, other orderings are valid on regular Collections. the use of the `orderedItems` term allows plain-JSON implementations to do exactly this.

View File

@ -0,0 +1,3 @@
## DO NOT VALIDATE @CONTEXT IF YOU DO NOT UNDERSTAND JSON-LD
you CANNOT check for the presence of `https://www.w3.org/ns/activitystreams` AT ALL -- the activitystreams context may be included within another context hosted elsewhere. or it may be excluded (although it SHOULD NOT). just ignore this property entirely if you don't understand it

View File

@ -0,0 +1,22 @@
## DON'T BE STRICT ABOUT VALIDATING ID
do NOT try to be overly strict about dereferencing IDs. some IDs may not be on your domain, or otherwise they may not be present at all, or they may be explicitly null. null or missing id indicates a transient activity.
### example: Follow semantics
Follows are realistically transient. it is therefore enough to:
- keep track of local state
- mutate state based on activities
if you receive an Accept/Reject Follow, check ONLY for the following:
- actor
- type == Accept/Reject
- object.actor
- object.type == Follow
- object.object == actor
if object is inlined, you don't need to check that object.id is local. the above is enough information, PROVIDED THAT you have a local pending follow request. if you do not have a pending follow, then DO NOT process an incoming Accept Follow. however, you may receive a Reject Follow at any time, indicating that you should destroy that follow relationship. note that you may also receive an Undo Accept Follow by some implementations. this is discouraged but should be handled as well
<https://github.com/misskey-dev/misskey/issues/9250>

View File

@ -0,0 +1,32 @@
## DO NOT CHECK TYPES DURING VALIDATION
an Actor has an `inbox` and `outbox`. that's it.
an Activity has an `actor`. that's it.
a Collection has `items` or `orderedItems`. that's it.
etc
## DON'T PANIC WHEN YOU SEE A TYPE YOU DON'T UNDERSTAND
say you understand tags of type Mention and Hashtag and Emoji. someone sends you a `tag` array with a raw Link. DON'T PANIC. the document is still valid. just filter out anything you don't understand, something like
```python
UNDERSTOOD_TAG_TYPES = set("Mention", "Hashtag", "Emoji")
document = json.loads(...)
tags = document.get('tag', [])
tags = [
tag
for tag in tags
if tag['type'] in UNDERSTOOD_TAG_TYPES
]
# do whatever you need to now
```
```javascript
const UNDERSTOOD_TAG_TYPES = new Set(["Mention", "Hashtag", "Emoji"])
let document = ...
tags = document.tag.filter(tag => tag.type in UNDERSTOOD_TAG_TYPES)
// do whatever you need to now
```

View File

@ -0,0 +1,5 @@
## max followers
https://github.com/mastodon/mastodon/issues/20089
max followers? mastodon has a MAX_FOLLOWS and MAX_FOLLOW_RATIO so why not MAX_FOLLOWERS?

View File

@ -0,0 +1,45 @@
## Message type
Message is an IntransitiveActivity?
```yaml
id: https://alice.social/activities/1
actor: https://alice.social
type: Message
to: https://bob.social
content: "hello bob"
```
representing rooms with context:
```yaml
id: https://alice.social/activities/1
actor: https://alice.social
type: Message
to: https://rooms.social/rooms/1/audience # inbox forwarding, probably
content: "hello room"
context: https://rooms.social/rooms/1 # verify inclusion how?
```
making the context into an actor:
```yaml
id: https://alice.social/activities/1
actor: https://alice.social
type: Message
to: # inbox forwarding, definitely
- https://rooms.social/rooms/1 # we need to deliver to the room actor
- https://rooms.social/rooms/1/followers # rooms.social or the room actor's client will forward to participants
content: "hello room"
context: https://rooms.social/rooms/1
```
use of bto/bcc?
```yaml
id: https://alice.social/activities/1
actor: https://alice.social
type: Message
content: "hello room" # arguably only the content needs to be signed? no need for canonicalization
context: https://rooms.social/rooms/1
```

View File

@ -0,0 +1,2 @@
+++
+++

View File

@ -0,0 +1,11 @@
### maybe objects shouldn't be inlined tho
spritely magenc golem ocappub etc etc etc
```yaml
id: alice.example/54078934249073290847321094/activity/1
actor: alice.example
type: Create
object: alice.example/54078934249073290847321094 # how to fetch this?
cc: [alice.example/followers, Public]
```

View File

@ -0,0 +1,13 @@
## exclude your own followers? send to someone else's followers? send to a room?
[tldr i should choose if i want my reply to go to my followers, or their followers, or just them, or all of the above, or whatever]
1. alice makes a post and sends it to her followers or whatever. optionally it can be made available to the public?
1. bob replies to alice, they send that to alice only, and *maybe* optionally to bob's followers. **this should be up to the user (bob).**
1. alice can then choose to redistribute that reply. **this should be up to the recipient (alice)** and also **this should be made clear to the replier (bob)**.
note that alice might allow bob's replies to be automatically redistributed, if alice trusts bob.
- bob may not want his reply to be redistributed though? so there should be a way for bob to signal that bob is okay with alice forwarding bob's message to alice's followers. perhaps by explicitly addressing alice's followers? bob might also make his reply explicitly anonymous and transient by using id: null or not providing id. either way, **this should be an explicit decision**

View File

@ -0,0 +1,2 @@
+++
+++

View File

@ -0,0 +1,7 @@
## Block/Mute reminders
anytime someone muted tries to reply, you respond with an Ignore
anytime someone blocked tries to interact, you respond with a Block
what if you do this *every single time* they try to reply/interact

View File

@ -0,0 +1,3 @@
## Federated mutes
as2 has an Ignore type so you could theoretically federate out mutes in the same way that blocks are currently federated