From 7cfcb173a6d6e470d1d64611888dd3ebc440fc2c Mon Sep 17 00:00:00 2001 From: silverpill Date: Tue, 19 Sep 2023 05:02:06 +0000 Subject: [PATCH] FEP-0837: Use Offer(Agreement) instead of Offer(Commitment) And replace "commitments" property with "clauses". --- fep/0837/fep-0837.md | 91 ++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/fep/0837/fep-0837.md b/fep/0837/fep-0837.md index 3441f0b..9640bb1 100644 --- a/fep/0837/fep-0837.md +++ b/fep/0837/fep-0837.md @@ -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.