We have created documentation on how exactly Lemmy federation works

@mro Feel free to make a pull request to add such a collection to Lemmy. I can help you with that, but dont have any time to implement it myself.

@Sebastian To be clear, the correct one is https://www.w3.org/ns/activitystreams#, and without # is incorrect?

https://www.w3.org/ns/activitystreams#h-introduction says so.

… and https://www.w3.org/TR/activitystreams-core/#extensibility fucks it up immediately.

… while https://www.w3.org/TR/activitystreams-vocabulary/#types using it with # again. lol. What a schizophrenic mess.

In the end you may have to match complete URIs anyway.

Thanks, fixed.

I am trying do describe the difference again.
I mean, isn’t it obvious.

as:Object
You just replace “as:” by the URL – now click
https://www.w3.org/ns/activitystreamsObject → “Document not found”
ActivityStreams 2.0 Terms → Yay
(https://www.w3.org/ns/activitystreams#Object - cause this software parsed the Link already)

I mean, it doesn’t make a difference for JSON-LD machine-consumers, only for people.
But then, I think it makes sense to use the one which resolves to valid URLs for e.g. JSON-LD and HTML/RDFa, which is
https://www.w3.org/ns/activitystreams#

2 Likes

wait, no, this is wrong, @mro seems to be confused about how namespacing works

the @context should be https://www.w3.org/ns/activitystreams without the # at the end.

what @mro cites in “introduction” is simply saying what the namespace is, not the context.

to be clear, the namespace has a base URI https://www.w3.org/ns/activitystreams# because this is the prefix to all the properties – Note expands to https://www.w3.org/ns/activitystreams#Note, actor expands to https://www.w3.org/ns/activitystreams#actor, and so on.

i encourage y’all to look at how JSON-LD Playground does expansion and compaction: JSON-LD Playground

for example, the following two are equivalent:

{
  "@context": ["https://www.w3.org/ns/activitystreams"],
  "type": "Note",
  "actor": "https://mastodon.social/users/trwnh"
}
{
  "@type": "https://www.w3.org/ns/activitystreams#Note",
  "https://www.w3.org/ns/activitystreams#actor": {
    "@id": "https://mastodon.social/users/trwnh"
  }
}

the # mark will be inserted for you by the json-ld processor, so it should not be included

1 Like

it’s magic :frowning:

(foo, bar, baz to reach the mandatory 20 characters per post. How silly)

@nutomic when I face e.g. the error message

error decoding response body: data did not match any variant of untagged enum PersonOrGroup

where does the how exactly Lemmy federation works explain what to do about it?

I am sending a Like server-to-server.

How exactly are you sending the like? That error means that Lemmy expects to parse either a Person or Group actor, not an activity.

it’s not magic – this bit gets downloaded and the whole context file gets parsed. if you look at https://www.w3.org/ns/activitystreams.jsonld then you can see in the @context that as is defined with the # mark.

The fact that a ‘#’ is inserted.

Hi @nutomic, thanks for the answer,

How exactly are you sending the like? That error means that Lemmy
expects to parse either a Person or Group actor, not an activity.

Like so:

POST /u/nutomic/inbox HTTP/1.1
host: lemmy.ml
date: Tue, 19 Jul 2022 06:20:58 GMT
digest: SHA-256=9vSP3acLKeCubMmMKC1ho2Bj8bGEt5ilPBQDtnL1y3c=
signature:
keyId=“https://demo.mro.name/seppo/activitypub/#main-key",algorithm=“rsa-sha256”,headers="(request-target)
host date
digest”,signature=“yrsKe53ZWLdOxnilUSoz4JyouPx8pq850OIWo1Fl/kwEyE6Am8is3epK4Rj+n3I90TBywzVDLSGeFH7OcslxoJHBZSlYC9+PsRFhC4w+puOWAb/eSHdDaek7Qn2FVHoKlen2r0qTH3pqwa5BKdHUHbZnXXMmVX4qRqX24UPyFFqaras9GG39n102aXKyFLhI1GGHX9IDCrSshHSU6YnBHNHNSDdLa5AMJaS+G1fC+kV7DL0HNDpPiqjZLkcrnIDurDnpzgidnmaCMHXWftMJlEJoS/T6SCSVs3h80+hxPlbBOx1qBBM8dPo6DXAFNU5FWZUVj1c6NXkIHuWGw6FaZA==”
content-type: application/activity+json
Accept: application/activity+json
User-Agent: #Seppo!/0.1 http://mro.name/seppo

{“@context”:“https://www.w3.org/ns/activitystreams",“actor”:“https://demo.mro.name/seppo/activitypub/”,“cc”:[“https://www.w3.org/ns/activitystreams#Public”],“id”:“https://lemmy.ml/post/171775#Like”,“object”:“https://lemmy.ml/post/171775”,“to”:[“https://lemmy.ml/u/nutomic”],“type”:"Like”}

Yes, a # gets inserted because it’s part of the namespace. Like = as:Like = ActivityStreams 2.0 Terms – this is all clearly shown in the JSON-LD context document I linked

In any case:

This looks to be invalid because you are attempting to use an id on a domain for which your actor does not have access.

Additionally, it is also invalid because trying to fetch https://lemmy.ml/post/171775#Like will not return the activity you are POSTing to nutomic’s inbox.

Merhaba Abdullah,

I appreciate your efforts a lot, thanks for caring.

Yes, a # gets inserted because it’s part of the namespace.

No, because some magic (json-ld engine?) does that in order to comply to
the namespace.

Like = as:Like = ActivityStreams 2.0 Terms – this is
all clearly shown in the JSON-LD context document I linked

what does that mean? The colon becomes a hashmark? Is that the magic?
Sad json-ld invented their own uri composition rules.

This looks to be invalid because you are attempting to use an id on
a domain for which

The id is a mere name I hope, right? Will it be dereferenced? When? Why?

your actor does not have access.

surely it has. Even you have, dereference it.

Additionally, it is also invalid because trying to fetch
https://lemmy.ml/post/171775#Like will not return the activity you
are POSTing to nutomic’s inbox.

Uh, does it have to? Where is that spec’d (interesting for me to see
what else to obey)?

So Lemmy wants to fetch itself what I just sent? Why do I send it in the
first place then?

I will try with ids on my domain only and see what the webserver logs
show.

@nutomic can you tell what’s going on?

it might be a good idea to read the json-ld specification too, since the activitystreams 2 is based on json-ld

the short summary is that json-ld is about “linked data” – basically, json documents can refer to other json documents by their id. the json-ld parser is like a normal json parser, but it can fetch other documents and construct a graph.

when working with json-ld, you have two main algorithms to consider: expansion and compaction. consider the following example from the playground:

{
  "@context": "http://schema.org/",
  "@type": "Person",
  "name": "Jane Doe",
  "jobTitle": "Professor",
  "telephone": "(425) 123-4567",
  "url": "http://www.janedoe.com"
}
  • expansion uses the @context definitions to turn all property names and any @value of @type = @id into a fully qualified URI.

the example above expands to the following (in other words, it is equivalent):

[
  {
    "@type": [
      "http://schema.org/Person"
    ],
    "http://schema.org/jobTitle": [
      {
        "@value": "Professor"
      }
    ],
    "http://schema.org/name": [
      {
        "@value": "Jane Doe"
      }
    ],
    "http://schema.org/telephone": [
      {
        "@value": "(425) 123-4567"
      }
    ],
    "http://schema.org/url": [
      {
        "@id": "http://www.janedoe.com"
      }
    ]
  }
]

this expanded form is an array of every node in the document. this document has 1 node, which contains an array of every property in standard json-ld notation, which includes some defined keys such as @id, @type, @value, etc.

  • compaction uses the expanded form and the associated @context definition to shorten any IRIs and inline the context back into the json-ld document.

the example above compacts to the following and is once again equivalent:

{
  "@context": "http://schema.org/",
  "type": "Person",
  "jobTitle": "Professor",
  "name": "Jane Doe",
  "telephone": "(425) 123-4567",
  "url": "http://www.janedoe.com"
}

when this processing is done, the @context is parsed for any IRIs which are fetched and then added to the overall context. you can also include context definitions inline, and the most recent definition is used.

yes, the separator for a namespace and its property is :, and this is because it needs to be distinct from a URL. remember, name = http://schema.org/name in this example, because we are using the schema.org namespace. but you probably know that activitystreams also has a name property with a different semantic meaning. what happens when we use two/multiple different contexts?

{
  "@context": ["http://schema.org/", "https://www.w3.org/ns/activitystreams"],
  "type": "Person",
  "jobTitle": "Professor",
  "name": "Jane Doe",
  "telephone": "(425) 123-4567",
  "url": "http://www.janedoe.com"
}

well, this is one possible compaction:

{
  "@context": "http://schema.org/",
  "type": "https://www.w3.org/ns/activitystreams#Person",
  "jobTitle": "Professor",
  "telephone": "(425) 123-4567",
  "https://www.w3.org/ns/activitystreams#name": "Jane Doe",
  "https://www.w3.org/ns/activitystreams#url": {
    "id": "http://www.janedoe.com"
  }
}

notice that name andurl are no longer in their short form. neither is the type value of Person. this is because compaction is done against a developer-provided context, and the json-ld playground seems to just use the first value of the sample’s context. if it was compacted against the context array, then these IRIs would be transformed back to their short forms.

now, suppose you needed to use two properties with the same short name. you could do that with compact namespacing or expanded namespacing. we can use the already-defined schema = https://schema.org/ and we can use the already-defined as = https://www.w3.org/ns/activitystreams# as the base URIs.

...
"@type": ["as:Person", "schema:Person"],
...

remember, the equivalent would be like so:

...
"@type": ["https://www.w3.org/ns/activitystreams#Person", "http://schema.org/Person"],
...

with respect to id assignment, ActivityPub specifies that ids must be assigned

with their authority belonging to that of their originating server

so no, it is not just a name, it is an unique identifier on your domain that is meant to be fetched later for verification or other purposes. if id is not provided or is null, then it is an anonymous or transient object:

Identifiers MUST be provided for activities posted in server to server communication, unless the activity is intentionally transient […] in which case the id MAY be omitted

2 Likes

thanks for your reminder (honestly), but the theory https://www.w3.org/DesignIssues/LinkedData.html of linked data aside for a moment (I once did e.g. https://codeberg.org/mro/librdf.sqlite) and even the peculiarities of json-ld, I am puzzled why the like of e.g. https://pixelfed.social/p/dk/279335294023634944 gives no return and remains without effect. The actor is modeled after https://gnusocial.net/user/1 and very similar to https://pixelfed.social/users/dk

The request comes inline because txt upload is not allowed here:

(request-target): post /users/dk/inbox
host: pixelfed.social
date: Thu, 21 Jul 2022 06:12:04 GMT
digest: SHA-256=llP4KBRK6U1f1PZ51nP1Ds4yD9k2wKNBjjh1Z9eONJg=
content-type: application/activity+json
signature: keyId="https://demo.mro.name/seppo/activitypub/#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="b0Ms5thCOlVRRSzNZKrc1gOEchIIVGltMDJJCquD08gKLIdvKkGfTbio0YpDwn9QwQqB4maXnWP1HOlkuq42d/17C7SW55ONfCXq6Vasbw0RXzUN+ASKDf2BCcZyqdtEhTDOPpBT6Twn6qm5veabVEcsaEiSEy+FW+sZJQ7FcRlNDiOgqYuwX1t84eJFoIB2gwpfzY00RtFx8guqprhAerCBCObvUPcxXCY8bYbDoMK50DLaVxaAU+T7sZ9S5Dzz+9WmftGICgL0Lv9IL6IGTSpXJUiB4bYoBa2KWlHetg7jlGbveLFM8GDmx/ooCq/nb9sbYZuAHVM6wRrEGuMa3A=="
Accept: application/activity+json
User-Agent: Seppo/0.1

{"type":"Dislike","@context":"https://www.w3.org/ns/activitystreams","id":"https://demo.mro.name/seppo/activitypub/likes.json#https://pixelfed.social/p/dk/279335294023634944","published":"2022-07-21T06:12:04-00:00","actor":"https://demo.mro.name/seppo/activitypub/","to":["https://pixelfed.social/users/dk"],"cc":["https://www.w3.org/ns/activitystreams#Public"],"object":"https://pixelfed.social/p/dk/279335294023634944"}

fixed a case typo, works now. https://codeberg.org/mro/seppo/commit/16ae3eba7aa6650573bb8f915528432d8b107df7

The original links posted here now return 404s. The new links appear to be these two:

https://join-lemmy.org/docs/en/administration/federation_getting_started.html
https://join-lemmy.org/docs/en/contributors/05-federation.html

1 Like