1
0
mirror of https://codeberg.org/fediverse/fep.git synced 2026-08-05 11:46:04 +00:00

FEP-0837: Use Offer(Agreement) instead of Offer(Commitment)

And replace "commitments" property with "clauses".
This commit is contained in:
silverpill
2023-09-19 05:02:06 +00:00
parent b395abbb1e
commit 7cfcb173a6
+53 -38
View File
@@ -125,7 +125,7 @@ Example:
### Publishing a proposal
Proposals can be linked to actors (if actor provides a service) or to other objects (if they represent economic resources) using [FEP-0ea0](https://codeberg.org/fediverse/fep/src/branch/main/fep/0ea0/fep-0ea0.md) payment links. Proposals can also be added to public collections, or be delivered to actor's followers, or announced by group actors.
Proposals can be linked to actors (if actor provides a service) or to other objects (if they represent economic resources) using [FEP-0ea0](https://codeberg.org/fediverse/fep/src/branch/main/fep/0ea0/fep-0ea0.md) payment links. Proposals can also be added to public collections, or be delivered to actor's followers using `Create` activity, or announced by group actors.
If FEP-0ea0 payment link is used, its `href` attribute MUST contain the proposal ID and its `rel` array MUST contain the string `https://w3id.org/valueflows/Proposal`. The value of `mediaType` attribute SHOULD be `application/ld+json; profile="https://www.w3.org/ns/activitystreams"`.
@@ -154,16 +154,34 @@ Consuming implementations which don't have marketplace features MAY display prop
## Responding to a proposal
### Agreements
An interested party responds to a proposal and then parties start negotiating to reach an **agreement**.
To respond to a proposal, an interested party MUST send an `Agreement` object wrapped in `Offer` activity to the actor indicated by the `attributedTo` property of the proposal. The proposing party MUST either commit to the action described in the proposal or send a rejection.
In the first case, the proposer finalizes the agreement and sends `Accept(Offer)` activity back to the interested party.
In the second case, the proposer sends `Reject(Offer)` activity. The interested party MAY send `Offer(Agreement)` activities many times until agreement is reached.
The representation of an agreement is a JSON document with the following properties:
- `id` (OPTIONAL): the unique global identifier of the agreement. This property is REQUIRED for finalized agreements.
- `type` (REQUIRED): the type of the object MUST be `Agreement`.
- `clauses` (REQUIRED): the list of commitments associated with the agreement.
**Commitments** are promised economic transactions. The representation of a commitment is a JSON document with the following properties:
- `id` (OPTIONAL): the unique global identifier of the commitment.
- `type` (REQUIRED): the type of the object MUST be `Commitment`.
- `satisfies` (REQUIRED): the reference to the intent.
- `resourceQuantity` (REQUIRED): the amount and unit of the economic resource.
- `id` (OPTIONAL): the unique global identifier of the commitment. This property is REQUIRED for commitments in finalized agreements. Implementations SHOULD use URL fragments to identify commitments associated with a given agreement. The RECOMMENDED fragment identifiers for commitments satisfying primary and reciprocal intents of the proposal are `primary` and `reciprocal`.
- `type` (REQUIRED): the type of the object MUST be `Commitment`.
- `satisfies` (REQUIRED): the reference to an intent.
- `resourceQuantity` (REQUIRED): the amount and unit of the economic resource.
To respond to a proposal, an interested party MUST send a `Commitment` object wrapped in `Offer` activity to the actor indicated by the `attributedTo` property of the proposal. The `satisfies` property of this `Commitment` object MUST reference the primary intent of the proposal. It is a transient object, therefore `id` MAY be omitted. If the value of `unitBased` property of the proposal is `false`, the amount of resource MUST be equal to the amount specified in the primary intent. Otherwise, the amount MUST be a multiple of the amount specified in the primary intent.
The first commitment MUST satisfy the primary intent of the proposal. The second commitment MUST satisfy the reciprocal intent of the proposal.
Example:
If the value of `unitBased` property of the proposal is `false`, the amount of resources specified in commitments MUST be equal to amounts specified in the proposal. Otherwise, amounts MUST be multiples of amounts specified in the proposal.
Example of an `Offer(Agreement)` activity:
```json
{
@@ -172,6 +190,8 @@ Example:
{
"om2": "http://www.ontology-of-units-of-measure.org/resource/om-2/",
"vf": "https://w3id.org/valueflows/",
"Agreement": "vf:Agreement",
"clauses": "vf:clauses",
"Commitment": "vf:Commitment",
"satisfies": "vf:satisfies",
"resourceQuantity": "vf:resourceQuantity",
@@ -183,42 +203,37 @@ Example:
"id": "https://social.example/objects/fc4af0d2-c3a1-409b-947c-3c5be29f49b0/offer",
"actor": "https://social.example/users/bob",
"object": {
"type": "Commitment",
"satisfies": "https://market.example/proposals/ddde9d6f-6f3b-4770-a966-3a18ef006930#primary",
"resourceQuantity": {
"hasUnit": "one",
"hasNumericalValue": "1"
}
"type": "Agreement",
"clauses": [
{
"type": "Commitment",
"satisfies": "https://market.example/proposals/ddde9d6f-6f3b-4770-a966-3a18ef006930#primary",
"resourceQuantity": {
"hasUnit": "one",
"hasNumericalValue": "1"
}
},
{
"type": "Commitment",
"satisfies": "https://market.example/proposals/ddde9d6f-6f3b-4770-a966-3a18ef006930#reciprocal",
"resourceQuantity": {
"hasUnit": "one",
"hasNumericalValue": "30"
}
}
]
},
"to": "https://market.example/users/alice"
}
```
## Agreements
Parties negotiate to reach an **agreement**.
After receiving `Offer(Commitment)` activity, the proposing party MUST either commit to action described in the proposal or send a rejection.
In the first case, the proposer sends `Accept(Offer)` activity back to the interested party.
In the second case, the proposer sends `Reject(Offer)` activity. The interested party MAY send `Offer(Commitment)` activities many times until agreement is reached.
### Accepting a response
The proposing party MUST create an agreement object that includes commitments corresponding to intents described in the proposal. If a similar agreement between parties already exists, it MAY be updated.
The representation of an agreement is a JSON document with the following properties:
- `id` (REQUIRED): the unique global identifier of the agreement.
- `type` (REQUIRED): the type of the object MUST be `Agreement`.
- `commitments` (REQUIRED): the list of commitments associated with the agreement. The first commitment MUST satisfy the primary intent of the proposal. The second commitment MUST satisfy the reciprocal intent of the proposal.
- `id` (REQUIRED): the unique global identifier of the commitment. Implementations SHOULD use URL fragments to identify commitments associated with a given agreement. The RECOMMENDED fragment identifiers for commitments satisfying primary and reciprocal intents of the proposal are `primary` and `reciprocal`.
- `url` (OPTIONAL): one or more links to resources associated with the agreement. An example of such resource is unique payment page (which can be represented as FEP-0ea0 link).
### Accepting an agreement
The `object` of `Accept` activity MUST be the `id` of the `Offer` activity previously sent to the actor.
`Accept` activity MUST have the `result` property containing the `Agreement` object. The first commitment of `Agreement` object MUST match the commitment in the `Offer` activity.
`Accept` activity MUST have the `result` property containing the `Agreement` object. The finalized agreement and corresponding commitments MUST have an `id` property. If a similar agreement between parties already exists, it MAY be updated and its `id` re-used. The quantities specified in the finalized agreement MUST match the quantities specified in `Agreement` object from the `Offer` activity.
The finalized agreement MAY have `url` property containing one or more links to resources associated with the agreement. An example of such resource is a payment page (which can be represented as FEP-0ea0 link).
Example:
@@ -230,7 +245,7 @@ Example:
"om2": "http://www.ontology-of-units-of-measure.org/resource/om-2/",
"vf": "https://w3id.org/valueflows/",
"Agreement": "vf:Agreement",
"commitments": "vf:commitments",
"clauses": "vf:clauses",
"Commitment": "vf:Commitment",
"satisfies": "vf:satisfies",
"resourceQuantity": "vf:resourceQuantity",
@@ -245,7 +260,7 @@ Example:
"result": {
"type": "Agreement",
"id": "https://market.example/agreements/edc374aa-e580-4a58-9404-f3e8bf8556b2",
"commitments": [
"clauses": [
{
"id": "https://market.example/agreements/edc374aa-e580-4a58-9404-f3e8bf8556b2#primary",
"type": "Commitment",
@@ -275,7 +290,7 @@ Example:
}
```
### Rejecting a response
### Rejecting an agreement
The `object` of `Reject` activity MUST be the `id` of the `Offer` activity previously sent to the actor.