vocabulary.md 18 KB


title: ForgeFed Vocabulary

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.

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.

Types

The base URI of all ForgeFed terms is https://forgefed.peers.community/ns#. The ForgeFed vocabulary has a JSON-LD context whose URI is https://forgefed.peers.community/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.peers.community/ns"
]

Activity Types

Push {#act-push}

URI: https://forgefed.peers.community/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.peers.community/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",
                "name": "Provide hints in sign-up form fields",
            }
        ]
    },
    "target": "https://example.dev/aviva/myproject/branches/master",
    "context": "https://example.dev/aviva/myproject"
}

Actor Types

Repository {#type-repository}

URI: https://forgefed.peers.community/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.peers.community/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>"
}

Object Types

Branch {#type-branch}

URI: https://forgefed.peers.community/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.peers.community/ns"
    ],
    "id": "https://example.dev/luke/myrepo/branches/master",
    "type": "Branch",
    "name": "master",
    "context": "https://example.dev/luke/myrepo",
    "ref": "refs/heads/master"
}

Commit {#type-commit}

URI: https://forgefed.peers.community/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.peers.community/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",
    "name": "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"
}

TicketDependency {#type-ticketdependency}

URI: https://forgefed.peers.community/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.peers.community/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"
}

Ticket {#type-ticket}

URI: https://forgefed.peers.community/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.peers.community/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
}

Properties

assignedTo {#prop-assignedto}

URI: https://forgefed.peers.community/ns#assignedTo

Notes: Identifies the Person assigned to work on this Ticket.

Domain: Ticket

Range: Person

Functional: Yes

Inverse of: (None)

Example:

isResolved {#prop-isresolved}

URI: https://forgefed.peers.community/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:

dependsOn {#prop-dependson}

URI: https://forgefed.peers.community/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:

dependedBy {#prop-dependedby}

URI: https://forgefed.peers.community/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:

dependencies {#prop-dependencies}

URI: https://forgefed.peers.community/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:

dependants {#prop-dependants}

URI: https://forgefed.peers.community/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:

repository (DEPRECATED) {#prop-repository}

URI: https://forgefed.peers.community/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:

description {#prop-description}

URI: https://forgefed.peers.community/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 that specifies a content and a mediaType. The mediaType SHOULD be "text/plain".

Functional: Yes

Inverse of: (None)

Example:

{
    "@context": [
        "https://www.w3.org/ns/activitystreams",
        "https://forgefed.peers.community/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",
    "name": "Add an installation script, fixes issue #89",

    "description": {
        "mediaType": "text/plain",
        "content": "It's about time people can install on their computers!"
    },
}

committedBy {#prop-committedby}

URI: https://forgefed.peers.community/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:

hash {#prop-hash}

URI: https://forgefed.peers.community/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:

committed {#prop-committed}

URI: https://forgefed.peers.community/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:

filesAdded {#prop-filesadded}

URI: https://forgefed.peers.community/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:

filesModified {#prop-filesmodified}

URI: https://forgefed.peers.community/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:

filesRemoved {#prop-filesremoved}

URI: https://forgefed.peers.community/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:

ref {#prop-ref}

URI: https://forgefed.peers.community/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.peers.community/ns"
    ],
    "id": "https://example.dev/luke/myrepo/branches/master",
    "type": "Branch",
    "name": "master",
    "context": "https://example.dev/luke/myrepo",

    "ref": "refs/heads/master"
}

team {#prop-team}

URI: https://forgefed.peers.community/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.peers.community/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"
    ]
}