FEP-1570: The FEP Ontology Process

Hello!

Please use this thread to discuss the proposed FEP and any potential problems or improvements that can be addressed.

Summary

Current usage of ActivityPub relies on the ActivityStreams namespace [AS NS] combined with custom extensions [Mastodon NS]. As far as I can tell, no best practices exist or a formal process to add new namespaces.

This FEP will remedy this by

  • Defining a process to create new FEP namespaces
  • Defining a process to add new entries to these FEP namespaces
  • Using this process to create a new FEP namespace
  • Using [FEP-61CE] as an example how the second process can be used.

A few things to point out:

  • This has some overlap with FEP-cb76: Content Addressed Vocabulary which proposes a URN namespace for FEPs, instead of an HTTPS URI.

  • You are defining the term fep using https://www.w3id.org/fep# if I understand correctly. However, you also refer to some fep-special term definition that is not actually defined in the proposal, nor is it clear how it differs functionally from the fep term definition. Do you expect the maintenance of multiple w3id purls? What makes a term definition “special”?

    • What if different FEPs conflict in their term definitions while using the same shorthand property name? This implies for future safety, each FEP should define its own namespace. Or, otherwise, a recommendation should be made to ensure terms and property names chosen do not conflict with current or potential future extensions. Generally, a “namespace” (more accurately, a vocabulary) is a collection of terms as defined under the same ontology, and I can see there being multiple different ontologies as projects pick and choose what they need.

    • Is there any consideration given to custom-defined contexts? It is not always the case that one will use a “premade” context, especially if they do not need much from it.

1 Like

Yes, there will most likely be clashes. We discussed namespaces before in A namespace for things defined in FEPs where I mentioned some options:

In addition to what you mention, I think we should avoid vendor-specific namespaces, unless well… they are purely relating to vendor-specific extensions. Right now the way these namespaces would proliferate would make little sense to me. I think a grouping into app-independent domains is necessary besides having an asExt for core vocabulary extensions, like e.g. ‘video’, ‘podcast’, ‘blog’, etc.

[…]

As to how domain-specific namespaces might look like… euhh idk, maybe:

  • https://w3id.org/activitystreams/extension/video
  • https://w3id.org/activitystreams/extension/microblog (now mastodon toot)
  • https://w3id.org/activitystreams/extension/microblog/posts (alternative)

Just an example, of course. Namespace can be anything…

And in my next comment an example:

{
  "@context": [
    "https://www.w3.org/ns/activitystreams",
    {
      "sc": "http://schema.org#",
      "video": "https://w3id.org/activitystreams/extension/video#",
      "framesPerSecond": {
        "@id": "video:framesPerSecond",
        "@type": "sc:Number"
      },
    }
  ],

  "id": "https://conf.tube/w/daJwZp7HhQFK5v3B9L89oY",
  "type": "Video",
  "framesPerSecond": 60
}

In the same comment I also mentioned how Peertube currently uses their own app-specific namespace in the @context and should I want to build an app in the same Social Video Platform domain, interoperable with Peertube but with one extra property, the current practice is that I would define yet another app-specific namespace… leading to a confusing proliferation of namespaces.

So this would create extra work for FEP editors, and also introduce a risk of conflicts which doesn’t currently exist.

What I fail to see are any benefits which this brings to the table. That is besides saving a few characters in federated messages.

i don’t think “domain-specific namespaces” makes sense. there shouldn’t be an arbitrary division between a “video” server and a “microblog” server. an activitypub server is an activitypub server. if we take inspiration from XMPP and the XEP specifications, the proper way forward would be to have a general fep namespace similar to urn:xmpp. this is why in FEP-cb76 (comment) i discussed using urn:publicid:fep as the base (although the current state of that FEP uses urn:sha256 which isn’t really backed by any RFC, though it is used in bittorrent magnet links nonetheless). in that regard, the proposal to use https://w3id.org/fep is possibly the next-least-bad thing – it is still a URL and therefore could possibly break, although the w3c permanent identifier cg promises they won’t. we could probably bikeshed about the exact URL to use, which i suspect would be driven mainly by what the intended purpose of the URL would be. if we grandfathered in terms from existing contexts, then the “fep” part could be a bit misleading, but this probably doesn’t matter.

honestly, the thing that makes the most sense to me would be to merge the two approaches – have https://w3id.org/fep be a URL that resolves to a JSON-LD context, but have the individual terms be defined by URNs. something like this would result in canReply mapping to urn:publicid:fep:5624:canReply

{
  "@id": "https://w3id.org/fep",
  "@context" : [
    {
      "fep": "urn:publicid:fep:",
      "canReply": "fep:5624:canReply"
    },
    "https://www.w3.org/ns/activitystreams"
  ]
}

the alternative would be to use URLs for the term definitions too. something like this would result in mapping canReply to https://w3id.org/fep/5624/canReply

{
  "@id": "https://w3id.org/fep",
  "@context" : [
    {
      "fep": "https://w3id.org/fep/",
      "canReply": "fep:5624:canReply"
    },
    "https://www.w3.org/ns/activitystreams"
  ]
}

personally i see no real use in having terms map to URLs except in the very niche case where you want the term/property to resolve to its own definition. URNs are superior in every other way because this problem space is fundamentally about naming things, not locating things. but it is, in the end, a preference. https://www.xfront.com/URLversusURN.pdf talks more about this.

having a consistent context, vocabulary, ontology, etc helps prevent the problem where two implementations define extensions that do the same thing, by giving the FEP process more power to define your extension in a commonly-owned namespace rather than needing your own project and project domain beforehand.

if you’re parsing “plain JSON”, then you can probably safely ignore this. if you’re “LD-aware”, then this is crucial to avoiding any confusion about where the extension is being defined and how it’s being defined. imagine a term such as actor. does it refer to the activitystreams “actor” who performed the activity? or does it refer to an “actor” who played a character in a filmed work? this example is already handled by https://schema.org/actor which is different than https://www.w3.org/ns/activitystreams#actor, but something similar could happen for some future FEP. in fact, you might define an FEP for proposing a common property name mapping some term to https://schema.org/actor! this would remove ambiguity for non-LD-aware activitystreams parsers. perhaps that FEP would define actedBy in such a way.

basically, there needs to be something like this in order to properly define extension terms without already having something like https://joinmastodon.org/ns or the many other project-defined URLs

1 Like

The main advantage of my proposal over FEP-cb76: Content Addressed Vocabulary is that it provides a method to tie documentation and specfification together. With FEP-cb76, you need to know the exact definition to understand the url.

Rereading it my writing is probably not clear enough, so I’m doing the main example:

This simplifies the task for the developer to understand a new namespace. I think this is called “improve developer experience” in tech evangelist speech.

Case study: lemmy

If I wanted to understand a current lemmy message, what would I naively do:

  • See the definition of “lemmy” in the @context and click on it: https://join-lemmy.org/ns#
  • I get a 404. I go to the base url https://join-lemmy.org/
  • I have to click on “docs” to get a search
  • I type in the term, I’m curious about “remove_data” in the search field
  • After searching again with my browser for “remove_data” on the page, I find what I’m looking for

With this FEP, this reduces down to 1 step, which is more developer friendly. This is not to say that the documentation of lemmy is bad. It’s basically the second best after ActivityStreams, I’m aware of. :+1: for that.

Also my FEP introduces a naming convention, which prevents bugs such as this.

Workload for editors:

As far as the work load goes, one should probably be able to automate the entire namespace, documentation creation and validation.

1 Like

I think we may have a clash of semantics here? With “domain” I meant the conceptual space for which you define a formal ontology/vocabulary (i.e. domain driven design ddd:domain, not dns:domain :slight_smile: ).

You can only use IRI’s in Linked Data, and preferably (SHOULD) they are dereferencable. In JSON-LD 1.1 chapter 3 it says:

Furthermore, developers and machines are able to use this IRI (by using a web browser, for instance) to go to the term and get a definition of what the term means. This process is known as IRI dereferencing.

And further down in chapter 8 Data Model:

An IRI (Internationalized Resource Identifier) is a string that conforms to the syntax defined in [RFC3987]. IRIs used within a graph SHOULD return a Linked Data document describing the resource denoted by that IRI when being dereferenced.

Hence I am not sure whether using a URN in the @context as per Content Addressed Vocabulary is valid JSON-LD at the moment.

(OT: I stumbled in an interesting paper in the context of Verifiable Credentials when searching for this, and it led me to check W3C DID specs. And creation of this topic → Linked Data versus ActivityPub )

The Decentralized Identifiers (DID) is very extensible, and I found this document that formally tracks all known extensions: DID Specification Registries. Something like this is usable for our FEP Ontology Process. Quoting the entire Chapter 3:

3. The Registration Process

Software implementers might find that the existing Decentralized Identifier Core specification [DID-CORE] is not entirely capable of addressing their use case and might need to add a new parameters, properties, or values to this registry in order to achieve their use case in a globally interoperable fashion. In order to add a new parameter, property, or value to this registry, an implementer MUST submit a modification request for this registry, as a pull request on the repository where this registry is hosted, where the modification request adheres to the following policies:

  1. Any addition to the DID Core Registries MUST specify a human readable description of the addition.
  2. Any name or value of a property or parameter MUST be indicative of its function. Avoid generic terms such as “myProperty” or “foo”.
  3. Any method name SHOULD avoid generic terms such as “mymethod” or “registry”.
  4. If there are copyright, trademark, or any intellectual property rights concerns, the addition and use MUST be authorized in writing by the intellectual property rights holder under a F/RAND license. Examples include DID Methods that use trademarked brand names, property names that utilize the titles of copyrighted works, and patented technology that would cause the use of the extension to require licensing a patent.
  5. Any addition MUST NOT create unreasonable legal, security, moral, or privacy issues that will result in direct harm to others. Examples of unacceptable additions include any containing racist language, technologies used to persecute minority populations, and unconsented pervasive tracking.
  6. Any addition to the DID Core Registries MUST link, via at least a URL, preferably a content-integrity protected one, to the defining specification so that implementers can implement the property.
  7. Any addition to the DID Core Registries that is a property or value, MUST specify a machine readable JSON-LD Context for the addition.
    • The JSON-LD Context MUST be included in full as part of the submission.
    • A namespace URI MUST be provided for the JSON-LD Context so that consumer implementations can consistently map a URI to the full context.
    • The URI provided MUST be persistent, and link all terms to their associated human readable descriptions.
    • The URI provided SHOULD resolve or link to the full context contents.
    • JSON-LD Contexts MUST be versioned and MUST NOT be date stamped.
    • JSON-LD Contexts SHOULD use scoped terms and MUST use the @protected feature to eliminate the possibility of term conflicts.
  8. Properties in the DID Core Registries MUST NOT be removed, only deprecated.

The Editors of the DID Specification Registries MUST consider all of the policies above when reviewing additions to the registry and MUST reject registry entries if they violate any of the policies in this section. Entities registering additions can challenge rejections first with the W3C DID Working Group and then, if they are not satisfied with the outcome, with the W3C Staff. W3C Staff need not be consulted on changes to the DID Specification Registries, but do have the final authority on registry contents. This is to ensure that W3C can adequately respond to time sensitive legal, privacy, security, moral, or other pressing concerns without putting an undue operational burden on W3C Staff.

Entries that are identified to cause interoperability problems MAY be marked as such at the discretion of the maintainers of this registry, and if possible, after consultation with the entry maintainer.

Any submission to the registries that meet all the criteria listed above will be accepted for inclusion. These registries enumerate all known mechanisms that meet a minimum bar, without choosing between them.

Human readable

Note that both JSON-LD and DID specs emphasize human-readable (specifically developers/implementers) quality of the document, in addition to machine-readability. Seen in that light names such as fep:5624:canReply while refering to the FEP’s ID lose readability. You can only know what they are about by dereferencing the IRI.

Also note that in terms of how FEP’s relate to ontologies there is no 1-to-1 mapping at the moment. And maybe there shouldn’t be one either, so that FEP’s and ontologies (which define AP vocab extensions) are entirely separate. This corresponds to a division I mentioned many times on this forum before of (in decreasing order of formality) having separation into 3 process tracks:

  1. Open standards → formal specifications (must use)
  2. FEP’s → common, recommended protocol extensions (should use)
  3. AP Vocabulary extensions → domain-specific ontologies (may use, depends on use cases)

Update: @helge’s FEP in this context is really the one that should be scoped to define 3) and is well underway to do so, looks like? :thinking:

AP Vocabulary extensions

I see that we agree a best-practice is to avoid project/vendor-specific namespaces where possible, and in the interest of broad interoperability.

Another example. One thing Lemmy defines in its @context is a property lemmy:moderators. Yesterday we heard that Discourse gets federation support and takes Lemmy as their guide. Discourse also has Admins, and - with current practice - might end up having a further extension with discourse:admins. Will they keep lemmy:moderators for interoperability or be consistent to their own app and have discourse:moderators?

These privilege levels are part of some common domain / ontology / vocabulary that should be defined once, and can then be shared by many different types of applications where it makes sense to have them. What should be the best name for this vocab extension? I don’t know. It should be as descriptive as possible, not too broad and not too narrow in scope.

An example vocab extension is the Security Vocabulary that both ActivityPub and DID use. See JSON-LD at: security-vocab context.

(Funny @trwnh, we have another sec:domain here :slight_smile: )

This is true for the FEP (as your context includes a SHA256 hash only), but I am at this point thinking of a different proposal, which is to use urn:publicid coupled with an fep namespace that has sub-namespaces for each FEP in particular (fep:5624 would contain terms for FEP-5624, such as fep:5624:canReply). This is analogous to XMPP’s XEP namespacing, such as urn:xmpp:omemo for XEP-0384: OMEMO Encryption.

This part is fine. I don’t have any issues with this; in fact, I think it is a good idea for bundling up all FEPs into a singular context for JSON-LD processors, similar to the schema dot org or the activitystreams contexts. I just think that the definitions shouldn’t necessarily be URLs. In other words, I think urn:publicid:fep:5624:canReply expresses more clearly “this is the canReply property as defined by FEP-5624” rather than https://w3id.org/fep#canReply which instead expresses “this is the canReply property as adopted by the FEP process”. The latter implies some sort of unity among the FEP process which isn’t really there. If we want it to be there, we need to change some things about the process, especially regarding how FEPs are superceded and how property names are defined/adopted:

  • Can anyone supercede anyone else’s FEP?
  • What if different projects adopt different FEPs, such as one project adopting the old term definition while another project adopts the replacement term definition? Do we discourage or disallow using certain names just because they have already been used by a past FEP?
    • Following this line of thought: Is it our responsibility to maintain a consistent vocabulary or ontology? It would be kind of like if the IETF decided that all RFCs must be consistent with each other.

Over on the XMPP side, the XEP process has an “experimental” phase in which namespaces (and names) can change. Taking OMEMO as an example, if we want to fetch the device list for any account, this has over time been defined as urn:xmpp:omemo:0:devicelist, urn:xmpp:omemo:1:devices, and currently urn:xmpp:omemo:2:devices – each namespace change represents an incompatible breaking change in the experimental spec. Sometimes the property names change.

Instead, the FEP process seems to have gone for a process that includes supercession by future FEPs rather than allowing “experimental” FEPs. The XEP has an authoritative namespace (urn:xmpp) registered to the XMPP Standards Foundation. The FEP process has no such thing. The proposal to use https://w3id.org/fep in effect establishes such a namespace for the FEP process, but it does not have any consideration for sub-namespaces. Sub-namespaces for XEPs are managed by authority of the XSF – you can register a sub-namespace like urn:xmpp:omemo as part of your XEP. Sub-namespaces for FEPs are not supported under this current proposal. To support sub-namespaces, the proposal would have to be changed such that it clearly establishes who has authority over the https://w3id.org/fep namespace, and it would also have to use / instead of # in its partial term definition – in other words, define fep as https://w3id.org/fep/ instead of https://w3id.org/fep# so that you can resolve sub-resources.

{
  "@context": [
    {
      "fep": "https://w3id.org/fep/",
      "canReply": {
        "@id": "fep:5624/canReply",
        "@type": "@id"
      }
    },
    "https://www.w3.org/ns/activitystreams"
  ],
  "canReply": "Public"
}

Changing the partial term definition is the easy part. Establishing authority over a common namespace is the hard part. And also, once again, using a URL at all means you depend on w3id.org staying up forever (and maintaining control over it). Otherwise it’s no different (actually slightly worse) than using a URN in the first place (because of DNS/hostname authority).

Yes, it’s nice to be able to take property names verbatim and resolve their definition. But this requires domain authority. Whereas, with a urn:publicid, there is no authority. I should note that urn:publicid is inspired by XML public identifiers, and the urn:publicid defined in RFC 3151 basically allows translating arbitrary strings into URNs. For our purposes, the public identifier fep:5624:canReply contains enough information to both specify a name without collision, as well as find the associated specification and definition ourselves (by searching for FEP-5624). Can you do this with a URL? Sure, if you’re willing to claim the necessary authority and responsibility.

So, if we’re willing to claim that necessary authority and responsibility, I think we should do so in a way that doesn’t expect consistency among every single FEP. Specifically, I would be opposed to URLs of the form https://w3id.org/fep#canReply, preferring URLs of the form https://w3id.org/fep/5624/canReply which clearly preserve the lineage of each term definition. Or, alternatively, we have to work out the rules on requesting that certain property names be adopted as term definitions under the common FEP namespace (so that once a term like canReply is “used up”, future FEPs know how to proceed regarding changing this definition or otherwise proposing a new term).

1 Like

IRIs include URNs. IRIs are just the internationalized form of URIs, which includes both URLs and URNs.

The SHOULD only applies when referring to nodes in a graph.

Which is to say: URNs are valid in JSON-LD. If they weren’t, then DIDs would not be allowed either (since DIDs are URNs).

Only insofar as a project/vendor/implementation/etc is willing to hold itself pursuant to the FEP process. I can imagine projects like Mastodon will want to continue using their namespace no matter what happens here. It will take some very good reasons to convince them to do otherwise. And the process of grandfathering in or otherwise reparenting existing extensions will not be something they want to do.

1 Like

Thanks for your clarification, @trwnh. I misread the ABNF thinking the first part in ihier-part was mandatory (the part having the //).

Still in the DID spec there are no examples of urn:foobar, did:foobar in the @context. They are all formatted as URL’s, and most likely all dereferencable to a JSON-LD document (didn’t test that, but for the the DID Specification Registries it is a requirement).

Yes, absolutely. The best-practice is wrt to broadest interoperability, and Mastodon’s toot is to be adopted as post-facto interoperability. Changing it would be very disruptive. Also any project is wholly free to make their own app-specific vocabs, of course.

Making reference to related Fediverse discussion started by @stevebate :

I think there are two main changes, that I should make to FEP-1570:

  • Rename it to “The FEP Vocabulary Extension Process”.
  • Use @trwnh’s plan to first define terms as fep-id:term, and then possibly include them as just terms. A canonical point for the transition fep-id:term → term would be if the FEP goes FINAL (and nobody objects).

A term of the form “fep-id:term” will be called experimental.

Finally @aschrijver has suggested including something as like Best Practices. Does somebody have some proposals for this? For reference:

i think using DIDs to define the context for DIDs would be a circular definition, no? :slight_smile:

this just has to do with json-ld processing. if you provide a string value in the @context then it is coerced into an @id (and then fetched and inlined into the document for processing). meaning you can type https://www.w3.org/ns/activitystreams and the json-ld processor will do an HTTP GET with the ld+json Accept type, and include whatever is served from there. it has nothing to do with an individual term – any term can be defined as any IRI, and IRIs include URNs.

well, you would want to adopt mastodon’s https://joinmastodon.org/ns# (it doesn’t matter what you call it) only if you cared about compatibility with mastodon and/or found its definitions useful. consider the case where the DID Core terms adopted alsoKnownAs from activitystreams – DID Core v1.0 Terms shows that the DID @context includes the security and activitystreams vocabs as well, and the only term adopted from activitystreams is https://www.w3.org/ns/activitystreams#alsoKnownAs. if you really cared to formalize some prior term, you could adopt it in the same way… but do you have the authority to (re)define it?

the problem with relying on mastodon’s namespace and terms is that you are bound to their expectations. for example, if you wanted to use featured for your concept of a “featured” collection, do you include only “posts” or do you also include “hashtags”? mastodon defines a separate featuredTags collection currently, but they might unify the two properties at some point and even integrate the concept of “featured accounts” into the same featured collection. or they might do something completely different. who knows? you’ll have to deal with that uncertainty that mastodon might change the meaning at any time.

luckily, there’s not actually much in there that you “need”. mastodon has been somewhat careful in adopting existing vocabularies where possible. maybe even too careful – the “profile fields” feature depends on an (incorrectly mapped) term from the schema vocab, and it could have been implemented using native activitystreams terms. see FEP-fb2a: Actor metadata for more details.

mostly, you might care about adopting Emoji for custom emoji, or blurhash for more colorful placeholders, or focalPoint for centering part of an image when using cover-fit. maybe you want suspended for marking an account as locked by moderators. everything else could possibly be better defined by some other vocabulary or FEP:

  • discoverable could be replaced by a fuller-defined set of flags indicating consent for various data representations and usages. (as it stands, this property is currently only used for the somewhat-defunct “profile directory” feature and also for the “trending posts” feature.)
  • votersCount is dependent on implementing polls in the same way as mastodon. (i’d honestly recommend or possibly take on myself a more “proper” definition of what polls should look like – the as:Question type as currently (ab)used is not really fit for this. but then again, it was based on a non-normative section…)
  • featured and featuredTags have the problems described above (their contents are unspecified and their definition is quite mastodon-specific)
  • IdentityProof is no longer used but i suspect there’s a better term or really a better way to express this use-case – probably DID verification methods, but i’m not 100% familiar with how those work

i’m not entirely sure of the whole landscape and which implementations have defined which terms and how many of those definitions are actually relevant (given that some implementers are “plain JSON” and not “LD-aware”), but i suspect a non-negligible number of extension properties can be formalized in an FEP or some other recommendation/proposal. it would have to be evaluated on a case-by-case basis.

1 Like

Rechecking the JSON-LD documentation, I realized that Vocabulary has some defined meaning inside it. Thus probably “The FEP Context Extension Process” would be a better name, as what it does is add stuff to the context provided through the fep process…

Any opinions?

You realize that URNs have to be registered, and it’s not a low bar

For content addressable hashes you can use the ni: scheme

The whole point of vocabs is anyone can make one e.g. at w3id.org, doesnt need to be fep/

You also have both context and vocab

I’ll say at this point almost all the vocabs ive seen are fundamentally bugged or wrong, including AS2.0

We may need to start a lot of this from scratch, to do it correctly

Here’s one I was working on lately for user profiles:

http://w3id.org/user

2 Likes

you could just call it “the fep context”? since you’re proposing not only an extension process but also just that we have a context at all / in general

i’m not sure about the other points or how they are relevant

“The FEP Context” also sounds good. I will descope a few things. In particular:

  • Discussing what I meant with objects like “fep-math”, where one defines “group” to be the real thing and values to be things like “monster”.

My reasoning is that it’s not necessary right now and makes things unnecessarily complicated.

So the technical contents will be:

  1. Introduce https://w3id.org/fep and define how it links to jsonld file and markdown description
  2. Allow every FEP to create entries of the form fep:XXXX:name, where XXXX is the FED id.
  3. Define a way to add name = fep:XXXX:name to https://w3id.org/fep

Adding an entry requires to both provide its definition and a description of its usage. Entries of type name should have a broad usage. Otherwise having something like

"@context": ["https://w3id.org/fep", 
{
    "name": "fep:XXXX:name"
}]

is considered preferable. I believe the above still retains many benefits from just name, i.e. linked documentation, clear process, while not causing any “namespace pollution”.

if we’re going with fep as https://w3id.org/fep/ i think this should be fep:XXXX/name so that iri expansion results in a proper url https://w3id.org/fep/XXXX/name. if we’re going with fep as urn:publicid:fep: then it should be fep:XXXX:name so that iri expansion results in a proper urn urn:publicid:fep:XXXX:name. given that you continually express preference for properties’ specifications being accessible via the web immediately, i would recommend the former.

the w3id mapping could look something like this:

  • https://w3id.org/fep accepting ld+json leads to the singular “fep context” that contains all terms
    • otherwise, it leads to some overview page for the fep process or namespace?
  • https://w3id.org/fep/XXXX accepting ld+json leads to an fep-specific context document?
    • otherwise, it leads to the FEP-XXXX document as submitted
  • https://w3id.org/fep/XXXX/name leads to a web page defining the term and linking to the relevant documents

considerations:

  • i float the idea above of having an fep-specific context document. this would be submitted with the fep and then you could just compile a machine-generated unifying context file from all FINAL proposals.
  • i suppose you could use https://w3id.org/fep/XXXX#name if you wanted the definition to be inlined into the fep document itself, but this should be consistent. on codeberg, for example, you would need a header with the exact name of the property which should not overlap with any other headers. this can lead to weird edge cases like, say you want to define a property called requirements but you also have a section #requirements. to avoid all this i recommend/prefer not using url fragments in term definitions.

taken together, i think this would imply something like the following structure in the git repo

context/
- context.jsonld
- 5624/
  - context.jsonld
  - canReply.{md? html? txt? no extension?}

context/5624/context.jsonld:

{
   "@context": {
    "canReply": { // define your property here
      "@id": "https://w3id.org/fep/5624/canReply", // give its full iri here
      "@type": "@id" // if coercion is needed, you include this bit
    }
  }
}

context/5624/canReply.txt (or whatever):

An advisory property signaling that replies from these actors will be accepted. Actors not included in this list may or may not have their replies discarded.

maybe recommend plaintext for these human-readable definitions