ForgeFed Vocabulary - draft - 2022-07-12 master b529345
1 Abstract
This document describes the ForgeFed vocabulary. Itâs intended to be an extension of the ActivityPub Vocabulary and provides additional vocabulary for federation of project management and version control system hosting and collaboration platforms.
2 Introduction
The ForgeFed Vocabulary describes a set of types and properties to be used by platforms that support the ForgeFed protocol. This specification describes only the new vocabulary called ForgeFed. The ForgeFed behavior specification describes how to use this vocabulary, along with standard ActivityPub vocabulary, to support the ForgeFed protocol.
3 Types
The base URI of all ForgeFed terms is https://forgefed.org/ns#
. The ForgeFed vocabulary has a JSON-LD context whose URI is https://forgefed.org/ns
. Implementers MUST either include the ActivityPub and ForgeFed contexts in their object definitions, or other contexts that would result with the ActivityPub and ForgeFed terms being assigned they correct full URIs. Implementers MAY include additional contexts and terms as appropriate.
A typical @context
of a ForgeFed object may look like this:
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
]
3.1 Activity Types
3.1.1 Push
URI: https://forgefed.org/ns#Push
Notes: Indicates that new content has been pushed to the Repository.
Extends: Activity
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://example.dev/aviva/outbox/reBGo",
"type": "Push",
"actor": "https://example.dev/aviva",
"to": [
"https://example.dev/aviva/followers",
"https://example.dev/aviva/myproject",
"https://example.dev/aviva/myproject/team",
"https://example.dev/aviva/myproject/followers"
],
"summary": "<p>Aviva pushed a commit to myproject</p>",
"object": {
"type": "OrderedCollection",
"totalItems": 1,
"items": [
{
"id": "https://example.dev/aviva/myproject/commits/d96596230322716bd6f87a232a648ca9822a1c20",
"type": "Commit",
"attributedTo": "https://example.dev/aviva",
"context": "https://example.dev/aviva/myproject",
"hash": "d96596230322716bd6f87a232a648ca9822a1c20",
"created": "2019-11-03T13:43:59Z",
"summary": "Provide hints in sign-up form fields",
}
]
},
"target": "https://example.dev/aviva/myproject/branches/master",
"context": "https://example.dev/aviva/myproject"
}
3.2 Actor Types
3.2.1 Repository
URI: https://forgefed.org/ns#Repository
Notes: Represents a version control system repository.
Extends: Object
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
"https://forgefed.org/ns"
],
"id": "https://dev.example/aviva/treesim",
"type": "Repository",
"publicKey": {
"id": "https://dev.example/aviva/treesim#main-key",
"owner": "https://dev.example/aviva/treesim",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhki....."
},
"inbox": "https://dev.example/aviva/treesim/inbox",
"outbox": "https://dev.example/aviva/treesim/outbox",
"followers": "https://dev.example/aviva/treesim/followers",
"team": "https://dev.example/aviva/treesim/team",
"name": "Tree Growth 3D Simulation",
"summary": "<p>Tree growth 3D simulator for my nature exploration game</p>"
}
3.3 Object Types
3.3.1 Branch
URI: https://forgefed.org/ns#Branch
Notes: Represents a named variable reference to a version of the Repository, typically used for committing changes in parallel to other development, and usually eventually merging the changes into the main history line.
Extends: Object
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://example.dev/luke/myrepo/branches/master",
"type": "Branch",
"name": "master",
"context": "https://example.dev/luke/myrepo",
"ref": "refs/heads/master"
}
3.3.2 Commit
URI: https://forgefed.org/ns#Commit
Notes: Represents a named set of changes in the history of a Repository. This is called âcommitâ in Git, Mercurial and Monotone; âpatchâ in Darcs; sometimes called âchange setâ. Note that Commit
is a set of changes that already exists in a repoâs history, while a Patch is a separate proposed change set, that could be applied and pushed to a repo, resulting with a Commit
.
Extends: Object
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://example.dev/alice/myrepo/commits/109ec9a09c7df7fec775d2ba0b9d466e5643ec8c",
"type": "Commit",
"context": "https://example.dev/alice/myrepo",
"attributedTo": "https://example.dev/bob",
"committedBy": "https://example.dev/alice",
"hash": "109ec9a09c7df7fec775d2ba0b9d466e5643ec8c",
"summary": "Add an installation script, fixes issue #89",
"description": {
"mediaType": "text/plain",
"content": "It's about time people can install on their computers!"
},
"created": "2019-07-11T12:34:56Z",
"committed": "2019-07-26T23:45:01Z"
}
3.3.3 TicketDependency
URI: https://forgefed.org/ns#TicketDependency
Notes: Represents a relationship between 2 Tickets, in which the resolution of one ticket requires the other ticket to be resolved too. It MUST specify the subject, object and relationship properties, and the relationship
property MUST be dependsOn.
Extends: Relationship
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"type": ["Relationship", "TicketDependency"],
"id": "https://example.dev/ticket-deps/2342593",
"attributedTo": "https://example.dev/alice",
"summary": "Alice's ticket depends on Bob's ticket",
"published": "2019-07-11T12:34:56Z",
"subject": "https://example.dev/alice/myproj/issues/42",
"relationship": "dependsOn",
"object": "https://dev.community/bob/coolproj/issues/85"
}
3.3.4 Ticket
URI: https://forgefed.org/ns#Ticket
Notes: Represents an item that requires work or attention. Tickets exist in the context of a project (which may or may not be a version-control repository), and are used to track ideas, proposals, tasks, bugs and more.
Extends: Object
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"type": "Ticket",
"id": "https://example.dev/alice/myrepo/issues/42",
"context": "https://example.dev/alice/myrepo",
"attributedTo": "https://dev.community/bob",
"summary": "Nothing works!",
"content": "<p>Please fix. <i>Everything</i> is broken!</p>",
"mediaType": "text/html",
"source": {
"content": "Please fix. *Everything* is broken!",
"mediaType": "text/markdown; variant=CommonMark"
},
"assignedTo": "https://example.dev/alice",
"isResolved": false
}
4 Properties
4.1 earlyItems
URI: https://forgefed.org/ns#earlyItems
Notes: In an ordered collection (or an ordered collection page) in which items (or orderedItems) contains a continuous subset of the collectionâs items from one end, earlyItems
identifiers a continuous subset from the other end. For example, if items
lists the chronologically latest items, earlyItems
would list the chrologically earliest items. The ordering rule for items in earlyItems
MUST be the same as in items
. For examle, if items
lists items in reverse chronogical order, then so does earlyItems
.
Domain: OrderedCollection
Range: Ordered list of [Object | Link]
Functional: No
Inverse of: (None)
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://dev.example/aviva/outbox",
"type": "OrderedCollection",
"totalItems": 712,
"orderedItems": [
"https://dev.example/aviva/outbox/712",
"https://dev.example/aviva/outbox/711",
"https://dev.example/aviva/outbox/710"
],
"earlyItems": [
"https://dev.example/aviva/outbox/3",
"https://dev.example/aviva/outbox/2",
"https://dev.example/aviva/outbox/1"
]
}
4.2 previousVersions
URI: https://forgefed.org/ns#previousVersions
Notes Specifies the previous versions of the subject, as an ordered list in reverse chronological order.
Domain: Object
Range: rdf:List
of objects of the same @type
as the subject
Functional: Yes
Inverse of: (None, but see currentVersion)
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://dev.example/aviva/notes/107",
"type": "Note",
"attributedTo": "https://dev.example/aviva",
"content": "I agree!!!!! (edit: fixed a typo)",
"previousVersions": [
"https://dev.example/aviva/notes/107_old_version",
"https://dev.example/aviva/notes/107_very_old_version",
"https://dev.example/aviva/notes/107_ancient_version"
]
}
4.3 currentVersion
URI: https://forgefed.org/ns#currentVersion
Notes Specifies the latest. current, up-to-date version of the subject. Once the subject specifies the currentVersion
property, it SHOULD NOT get any changes to any other properties. The exception is currentVersion
itself, which MUST be updated whenever needed, to always point to the latest version.
Domain: Object
Range: Object, of the same @type
as the subject
Functional: Yes
Inverse of: (None, but see previousVersions)
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://dev.example/aviva/notes/107_old_version",
"type": "Note",
"attributedTo": "https://dev.example/aviva",
"content": "I agree!!111",
"currentVersion": "https://dev.example/aviva/notes/107"
}
4.4 assignedTo
URI: https://forgefed.org/ns#assignedTo
Notes: Identifies the Person assigned to work on this Ticket.
Domain: Ticket
Range: Person
Functional: Yes
Inverse of: (None)
Example:
4.5 isResolved
URI: https://forgefed.org/ns#isResolved
Notes: Specifies whether the Ticket is closed, i.e. the work on it is done and it doesnât need to attract attention anymore.
Domain: Ticket
Range: xsd:boolean
Functional: Yes
Inverse of: (None)
Example:
4.6 resolvedBy
URI: https://forgefed.org/ns#resolvedBy
Notes: Identifies the Actor who has resolved the Ticket, or the activity that has resolved the Ticket.
Domain: Ticket
Range: Object than is an actor, or Activity
Functional: Yes
Inverse of: (None)
Example:
4.7 resolved
URI: https://forgefed.org/ns#resolved
Notes: For a resolved Ticket, specifies the time the Ticket has been resolved.
Domain: Ticket
Range: xsd:dateTime
Functional: Yes
Inverse of: (None)
Example:
4.8 dependsOn
URI: https://forgefed.org/ns#dependsOn
Notes: Identifies one or more tickets on which this Ticket depends, i.e. it canât be resolved without those tickets being resolved too.
Domain: Ticket
Range: Ticket
Functional: No
Inverse of: dependedBy
Example:
4.9 dependedBy
URI: https://forgefed.org/ns#dependedBy
Notes: Identifies one or more tickets which depend on this Ticket, i.e. they canât be resolved without this tickets being resolved too.
Domain: Ticket
Range: Ticket
Functional: No
Inverse of: dependsOn
Example:
4.10 dependencies
URI: https://forgefed.org/ns#dependencies
Notes: Identifies a Collection of TicketDependency which specify tickets that this Ticket depends on, i.e. this ticket is the subject of the dependsOn relationship.
Domain: Ticket
Range: Collection of items of type TicketDependency
Functional: Yes
Inverse of: (None)
Example:
4.11 dependants
URI: https://forgefed.org/ns#dependants
Notes: Identifies a Collection of TicketDependency which specify tickets that depends on this Ticket, i.e. this ticket is the object of the dependsOn relationship. Often called âreverse dependenciesâ.
Domain: Ticket
Range: Collection of items of type TicketDependency
Functional: Yes
Inverse of: (None)
Example:
4.12 repository (DEPRECATED)
URI: https://forgefed.org/ns#repository
Notes: Identifies the repository to which a commit belongs. DEPRECATED: Use the standard ActivityPub context
property instead.
Domain: Commit
Range: Repository
Functional: Yes
Inverse of: (None)
Example:
4.13 description
URI: https://forgefed.org/ns#description
Notes: Specifies the description text of a Commit, which is an optional possibly multi-line text provided in addition to the one-line commit title. The range of the description
property works the same way the range of the ActivityPub source property works.
Domain: Commit
Range: Object, specifying content and mediaType. The mediaType
SHOULD be "text/plain"
.
Functional: Yes
Inverse of: (None)
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://example.dev/alice/myrepo/commits/109ec9a09c7df7fec775d2ba0b9d466e5643ec8c",
"type": "Commit",
"context": "https://example.dev/alice/myrepo",
"attributedTo": "https://example.dev/bob",
"hash": "109ec9a09c7df7fec775d2ba0b9d466e5643ec8c",
"created": "2019-07-11T12:34:56Z",
"summary": "Add an installation script, fixes issue #89",
"description": {
"mediaType": "text/plain",
"content": "It's about time people can install on their computers!"
},
}
4.14 cloneUri
URI: https://forgefed.org/ns#cloneUri
Notes: An endpoint that can be used with a VCS protocol such as Git or Mercurial to access a given repository.
Domain: Repository
Range: Object
Functional: No
Inverse of: (None)
Example:
4.15 committedBy
URI: https://forgefed.org/ns#committedBy
Notes: Identifies the actor (usually a person, but could be something else, e.g. a bot) that added a set of changes to the version-control Repository. Sometimes the author of the changes and the committer of those changes arenât the same actor, in which case the committedBy
property can be used to specify who added the changes to the repository. For example, when applying a patch to a repository, e.g. a Git repository, the author would be the person who made the patch, and the committer would be the person who applied the patch to their copy of the repository.
Domain: Commit
Range: Object
Functional: Yes
Inverse of: (None)
Example:
4.16 hash
URI: https://forgefed.org/ns#hash
Notes: Specifies the hash associated with a Commit, which is a unique identifier of the commit within the Repository, usually generated as a cryptographic hash function of some (or all) of the commitâs data or metadata. For example, in Git it would be the SHA1 hash of the commit; in Darcs it would be the SHA1 hash of the patch info.
Domain: Commit
Range: xsd:string
of hexadecimal digit ASCII characters
Functional: Yes
Inverse of: (None)
Example:
4.17 committed
URI: https://forgefed.org/ns#committed
Notes: Specifies the time that a set of changes was committed into the Repository and became a Commit in it. This can be different from the time the set of changes was produced, e.g. if one person creates a patch and sends to another, and the other person then applies the patch to their copy of the repository. We call the former event âcreatedâ and the latter event âcommittedâ, and this latter event is specified by the committed
property.
Domain: Commit
Range: xsd:dateTime
Functional: Yes
Inverse of: (None)
Example:
4.18 filesAdded
URI: https://forgefed.org/ns#filesAdded
Notes: Specifies a filename, as a relative path, relative to the top of the tree of files in the Repository, of a file that got added in this Commit, and didnât exist in the previous version of the tree.
Domain: Commit
Range: xsd:string
Functional: No
Inverse of: (None)
Example:
4.19 filesModified
URI: https://forgefed.org/ns#filesModified
Notes: Specifies a filename, as a relative path, relative to the top of the tree of files in the Repository, of a file that existed in the previous version of the tree, and its contents got modified in this Commit.
Domain: Commit
Range: xsd:string
Functional: No
Inverse of: (None)
Example:
4.20 filesRemoved
URI: https://forgefed.org/ns#filesRemoved
Notes: Specifies a filename, as a relative path, relative to the top of the tree of files in the Repository, of a file that existed in the previous version of the tree, and got removed from the tree in this Commit.
Domain: Commit
Range: xsd:string
Functional: No
Inverse of: (None)
Example:
4.21 ref
URI: https://forgefed.org/ns#ref
Notes: Specifies an identifier for a Branch, that is used in the Repository to uniquely refer to it. For example, in Git, ârefs/heads/masterâ would be the ref
of the master branch.
Domain: Branch
Range: xsd:string
Functional: Yes
Inverse of: (None)
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://example.dev/luke/myrepo/branches/master",
"type": "Branch",
"name": "master",
"context": "https://example.dev/luke/myrepo",
"ref": "refs/heads/master"
}
4.22 team
URI: https://forgefed.org/ns#team
Notes:: Specifies a Collection of actors who are working on the object, or responsible for it, or managing or administrating it, or having edit access to it. For example, for a Repository, it could be the people who have push/edit access, the âcollaboratorsâ of the repository.
Domain: Object
Range: Collection of actors
Functional: Yes
Inverse of: (None)
Example:
A repository https://dev.example/aviva/treesim:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
"https://forgefed.org/ns"
],
"id": "https://dev.example/aviva/treesim",
"type": "Repository",
"publicKey": {
"id": "https://dev.example/aviva/treesim#main-key",
"owner": "https://dev.example/aviva/treesim",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhki....."
},
"inbox": "https://dev.example/aviva/treesim/inbox",
"outbox": "https://dev.example/aviva/treesim/outbox",
"followers": "https://dev.example/aviva/treesim/followers",
"name": "Tree Growth 3D Simulation",
"summary": "<p>Tree growth 3D simulator for my nature exploration game</p>",
"team": "https://dev.example/aviva/treesim/team"
}
The repositoryâs team https://dev.example/aviva/treesim/team:
{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "https://dev.example/aviva/treesim/team",
"type": "Collection",
"totalItems": 3,
"items": [
"https://dev.example/aviva",
"https://dev.example/luke",
"https://code.community/users/lorax"
]
}
4.23 ticketsTrackedBy
URI: https://forgefed.org/ns#ticketsTrackedBy
Notes: Identifies the actor which tracks tickets related to the given object. This is the actor to whom you send tickets youâd like to open against the object.
Domain: Object
Range: Object that is an actor
Functional: Yes
Inverse of: tracksTicketsFor
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://dev.example/aviva/treesim",
"type": "Repository",
"name": "Tree Growth 3D Simulation",
"summary": "<p>Tree growth 3D simulator for my nature exploration game</p>",
"ticketsTrackedBy": "https://bugs.example/projects/treesim"
}
4.24 tracksTicketsFor
URI: https://forgefed.org/ns#tracksTicketsFor
Notes: Identifies objects for which which this ticket tracker tracks tickets. When youâd like to open a ticket against those objects, you can send them to this tracker.
Domain: Object that is an actor
Range: Object
Functional: No
Inverse of: ticketsTrackedBy
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://bugs.example/treesim",
"type": "Project",
"tracksTicketsFor": [
"https://dev.example/aviva/liblsystem",
"https://dev.example/aviva/3d-tree-models",
"https://dev.example/aviva/treesim"
]
}
4.25 sendPatchesTo
URI: https://forgefed.org/ns#sendPatchesTo
Notes: Identifies the actor which tracks patches and merge requests related to the given repository. This is the actor to whom you send patches and merge requests youâd like to open against the repository.
Domain: Repository
Range: Object that is an actor
Functional: Yes
Inverse of: tracksPatchesFor
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://dev.example/aviva/treesim",
"type": "Repository",
"name": "Tree Growth 3D Simulation",
"summary": "<p>Tree growth 3D simulator for my nature exploration game</p>",
"sendPatchesTo": "https://bugs.example/projects/treesim"
}
4.26 tracksPatchesFor
URI: https://forgefed.org/ns#tracksPatchesFor
Notes: Identifies repositories for which which this patch and merge request tracker tracks patches and merge requests. When youâd like to open patches or merge requests against those repositories, you can send them to this tracker.
Domain: Object that is an actor
Range: Repository
Functional: No
Inverse of: sendPatchesTo
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://project.example/treesim",
"type": "Project",
"tracksPatchesFor": [
"https://dev.example/aviva/liblsystem",
"https://dev.example/aviva/3d-tree-models",
"https://dev.example/aviva/treesim"
]
}
4.27 forkedFrom
URI: https://forgefed.org/ns#forkedFrom
Notes: Identifies the Repositorys which this Repository was created as a fork of, i.e. by cloning it.
Domain: Repository
Range: Repository
Functional: Yes
Inverse of: forks
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://example.dev/alice/myfork/",
"type": "Repository",
"forkedFrom": {
"type": "Repository",
"id": "https://example.dev/luke/myrepo/"
}
}
4.28 forks
URI: https://forgefed.org/ns#forks
Notes: Identifies an OrderedCollection of Repositorys which were created as forks of this Repository, i.e. by cloning it. The order of the collection items is by reverse chronological order of the forking events.
Domain: Repository
Range: OrderedCollection of items of type Repository
Functional: Yes
Inverse of: forkedFrom
Example:
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://forgefed.org/ns"
],
"id": "https://example.dev/luke/myrepo/",
"type": "Repository",
"forks": {
"type": "OrderedCollection",
"totalItems": 1,
"orderedItems": [
{
"id": "https://example.dev/alice/myfork/",
"type": "Repository",
}
]
},
}