Page MenuHomePhabricator

Implement a MW API module for interacting with Jade entities
Closed, ResolvedPublic

Description

See https://www.mediawiki.org/wiki/JADE/Use_cases

Discussion/rules:

  • A Jade page can be created without any facets, but it serves little purpose. It might only really be possible to arrive here by creating a proposal + endorsement and then deleting it.
  • Each facet may only appear once. This is largely enforced by object member naming in JSON (e.g. "editquality" is a unique identifier of the "editquality" facet)
  • Each facet may have zero or more proposals, but the data for a proposal must be unique. E.g. for "ediitquality" there are only 4 options for proposals: damaging, goodfaith; damaging, badfaith; good, goodfaith; good, badfaith (unlikely, probably a mistake)
  • Each proposal may have zero or more endorsements. A user may only endorse one proposal within a facet.
  • A proposal is identified by: entity data, facet, and label data.
  • An endorsement is identified by: entity data, facet, and user data. (Note that label data is implied because a user can only endorse one proposal per facet)

Event Timeline

Harej triaged this task as Medium priority.Nov 14 2018, 10:59 PM
Harej raised the priority of this task from Medium to High.
Harej renamed this task from Write full specification for the JADE API to Write full specification for the Jade API.Apr 15 2019, 10:22 PM
Harej removed Harej as the assignee of this task.May 1 2019, 8:08 PM
Harej lowered the priority of this task from High to Medium.
Harej added a subscriber: Harej.

The goal with our API endpoints is to minimize the amount of complexity that an API user needs to deal with. Instead, we should try to give them a simple endpoint and just *do the right thing*. Still we also want to give people the power to *do an exact thing*. It looks like the convention is to use all lower-case names without delimiters (aka "flat case"). There's also precident for sending JSON in parameters. See https://www.wikidata.org/w/api.php?action=help&modules=wbsetclaim for an example JSON blob argument.

Thoughts:

  • Either allow people to access Jade based on page title or on fields representing entitytype and id.
  • We could encode the Jade entity info as a JSON blob. That would give us more flexibility for indentifying an entity using more fields.
  • Don't require label data when interacting with an endorsement. Since endorsements are identifiable from facet and user info, data is superfluous.
  • Drop proposalid/labelid. It serves no clear purpose.
  • Included some errors that are specific to Jade. E.g. You can't delete the preferred proposal unless it is the last proposal for a facet.
  • Included some warnings that would cue users into follow-up actions. E.g. You've endorsed a non-preferred proposal.
  • All endpoints return the JSON of the entire entity after applying the update.

1jadeproposeorendorse -- Catch all, routing method that tries to *do the right thing*
2 @param title (str) The encoded entity name. (E.g. "Jade:Diff/123456") [required if entitytype or entityid are not set]
3 @param entitydata (json) The type of Jade entity (E.g., {"type": "diff", "id": 3245678}) [required if title not set]
4 @param facet (str) The facet of the entity being labeled [required]
5 @param labeldata (json) The relevant new label data [required]
6 @param notes (str) Notes to save when creating a new proposal (A warning will be raised if a proposal already exists. Notes will not be automatically overwritten.)
7 @param endorsementcomment (str) Comment to leave with the endorsement. Defaults to "As proposer" if not set and creating new proposal.
8 @param origin (str) A structured string representing what the user was looking at when they made this judgment [required]
9 @param comment (str) Revision summary
10 @param token (str) [required]
11 @warning endorsingnonpreferredproposal -- This action resulted in creating an endorsement for a proposal that is not flagged as preferred.
12 @warning nochange -- This action would result in no change. {user} has already endorsed {labeldata}.
13
14jadecreateandendorse -- Creates a new proposal and files an endorsement. If the user already endorsed another proposal within the facet, move the user's endorsement to the new proposal.
15 @param title (str) The encoded entity name. (E.g. "Jade:Diff/123456") [required if entitytype or entityid are not set]
16 @param entitydata (json) The type of Jade entity (E.g., {"type": "diff", "id": 3245678}) [required if title not set]
17 @param facet (str) The facet of the entity being labeled [required]
18 @param labeldata (json) The relevant new label data [required]
19 @param notes (str) Notes to save when creating a new proposal (A warning will be raised if a proposal already exists. Notes will not be automatically overwritten.)
20 @param endorsementcomment (str) Comment to leave with the endorsement. Defaults to "As proposer" if not set.
21 @param origin (str) A structured string representing what the user was looking at when they made this judgment [required]
22 @param comment (str) Revision summary
23 @param nomove (str) If set, do not move an endorsement. Instead throw an error.
24 @param token (str) [required]
25 @error proposalexists -- If a proposal with the specified data already exists
26 @warning endorsingnonpreferredproposal -- This action resulted in creating an endorsement for a proposal that is not flagged as preferred.
27
28jadeendorse -- Adds a new endorsement to a proposal
29 @param title (str) The encoded entity name. (E.g. "Jade:Diff/123456") [required if entitytype or entityid are not set]
30 @param entitydata (json) The type of Jade entity (E.g., {"type": "diff", "id": 3245678}) [required if title not set]
31 @param facet (str) The facet of the entity being labeled [required]
32 @param labeldata (json) The relevant label data [required]
33 @param endorsementcomment (str) Comment to leave with the endorsement. Defaults to "As proposer" if not set.
34 @param origin (str) A structured string representing what the user was looking at when they made this judgment [required]
35 @param comment (str) Revision summary
36 @param nomove (bool) If set, do not move an endorsement. Instead throw an error. If true, warn that the endorsement was moved.
37 @param token (str) [required]
38 @error proposalnotfound -- Could not find a proposal with matching "data"
39 @warning endorsingnonpreferredproposal -- This action resulted in creating an endorsement for a proposal that is not flagged as preferred.
40 @warning nochange -- This action would result in no change. {user} has already endorsed {labeldata}.
41
42jademoveendorsement -- Moves an endorsement to a new proposal. If "data" matches the currently endorsed proposal, make no change (except maybe to endorsement comment)
43 @param title (str) The encoded entity name. (E.g. "Jade:Diff/123456") [required if entitytype or entityid are not set]
44 @param entitydata (json) The type of Jade entity (E.g., {"type": "diff", "id": 3245678}) [required if title not set]
45 @param facet (str) The facet of the entity [required]
46 @param labeldata (json) The relevant new label data [required]
47 @param comment (str) Revision summary
48 @param endorsementcomment (str) Leave unchanged if unset.
49 @param token (str) [required]
50 @error proposalnotfound -- Could not find a proposal with matching "data"
51 @warning endorsingnonpreferredproposal -- This action resulted in an endorsement for a proposal that is not flagged as preferred.
52 @warning nochange -- This action would result in no change. {user} has already endorsed {labeldata}.
53
54jadedeleteproposal -- Removes a specific proposal
55 @param title (str) The encoded entity name. (E.g. "Jade:Diff/123456") [required if entitytype or entityid are not set]
56 @param entitydata (json) The type of Jade entity (E.g., {"type": "diff", "id": 3245678}) [required if title not set]
57 @param facet (str) The facet of the entity [required]
58 @param labeldata (json) The relevant label data [required]
59 @param comment (str) Revision summary
60 @param token (str) [required]
61 @error proposalnotfound -- Could not find a proposal with matching "data"
62 @error proposalispreferred -- Cannot delete a preferred proposal except when it is the only remaining proposal for a facet. You must set another proposal to be "preferred"
63
64jadedeleteendorsement -- Removes the user's endorsement
65 @param title (str) The encoded entity name. (E.g. "Jade:Diff/123456") [required if entitytype or entityid are not set]
66 @param entitydata (json) The type of Jade entity (E.g., {"type": "diff", "id": 3245678}) [required if title not set]
67 @param facet (str) The facet of the entity [required]
68 @param user_id (int) If set, remove this user's endorsement [default: self] [required one of (user_id, global_id, ip)]
69 @param global_id (int) If set, remove this user's endorsement (If centralauth is in use) [default: self] [required one of (user_id, global_id, ip)]
70 @param ip (str) If set, remove this user's endorsement [default: self] [required one of (user_id, global_id, ip)]
71 @param comment (str) Revision summary
72 @param token (str) [required]
73 @error endorsementnotfound -- Could not find an endorsement from the target user
74
75jadesetpreference -- Moves the preference bit from one proposal to another within a facet
76 @param title (str) The encoded entity name. (E.g. "Jade:Diff/123456") [required if entitytype or entityid are not set]
77 @param entitydata (json) The type of Jade entity (E.g., {"type": "diff", "id": 3245678}) [required if title not set]
78 @param facet (str) The facet of the entity [required]
79 @param labeldata (json) The relevant label data [required]
80 @param token (str) [required]
81 @error proposalnotfound -- Could not find a proposal with matching "data"
82 @warning nochange -- This action would result in no change. {labeldata} is already set as "preferred"
83
84jadeupdateproposal
85 @param title (str) The encoded entity name. (E.g. "Jade:Diff/123456") [required if entitytype or entityid are not set]
86 @param entitydata (json) The type of Jade entity (E.g., {"type": "diff", "id": 3245678}) [required if title not set]
87 @param facet (str) The facet of the entity [required]
88 @param labeldata (json) The relevant label data [required]
89 @param notes (str) The new notes field for the proposal [required]
90 @param token (str) [required]
91 @error proposalnotfound -- Could not find a proposal with matching "data"
92 @warning nochange -- This action would result in no change. Notes are identical.
93
94jadeupdateendorsement
95 @param title (str) The encoded entity name. (E.g. "Jade:Diff/123456") [required if entitytype or entityid are not set]
96 @param entitydata (json) The Jade entity (E.g., {"type": "diff", "id": 3245678}) [required if title not set]
97 @param facet (str) The facet of the entity [required]
98 @param user_id (int) If set, remove this user's endorsement [default: self] [required one of (user_id, global_id, ip)]
99 @param global_id (int) If set, remove this user's endorsement (If centralauth is in use) [default: self] [required one of (user_id, global_id, ip)]
100 @param ip (str) If set, remove this user's endorsement [default: self] [required one of (user_id, global_id, ip)]
101 @param endorsementcomment (str) The new comment field for the endorsement
102 @param token (str) [required]
103 @error endorsementnotfound -- Could not find an endorsement from the target user
104 @warning nochange -- This action would result in no change. Endorsement comments are identical.
105
106jadegetlabels
107 @param titles (str, multiple) The encoded entity name. (E.g. "Jade:Diff/123456") [required if entitytype or entityid are not set]
108 @param entitydata (json, multiple) The Jade entity (E.g., {"type": "diff", "id": 3245678}) [required if title not set]
109 @param facet (str, multiple) Which facets to include in the response [default: all]
110 @param props (str, multiple) Which facet parts to include endorsements, notes, nonpreferred. [default: notes]

Halfak updated the task description. (Show Details)

We should auto-generate structured edit summaries for these API endpoints.

Our goal here is to have semi-structured, human-readable content in the comment.text_comment field (part revision metadata). A user should be able to look at the sequence of edits to a Jade page and know roughly what happened just by reading through the comments. Wikibase does something like this already. Let's do our best to follow their example for formatting. See https://quarry.wmflabs.org/query/37968 for a recent set of comments for edits to Wikidata items.

  • /* jade-createandendorseproposal */ <proposal data> "<notes field>": <comment>
  • /* jade-createproposalandmoveendorsement */ <new proposal data> "<notes field>": <comment>
  • /* jade-endorseproposal */ <proposal data> "<comment field>": <comment>
  • /* jade-moveendorsement */ from <old proposal data> to <new proposal data> "<comment field>": <comment>
  • /* jade-deleteproposal|<# of endorsements> */ <proposal data>: <comment>
  • /* jade-deleteendorsement */ <proposal data> by <user>: <comment>
  • /* jade-setpreference */ <proposal data> "<notes field>": <comment>
  • /* jade-updateproposal */ <proposal data> "<new notes field>": <comment>
  • /* jade-updateendorsement */ "<new comment field>": <comment>
  • Undid revision <revid> by <user>: <comment> (This is a standard auto-generated comment)

I just realized we should add endpoints for *getting* Jade data. I just updated P8830 to include "jadegetlabels".

I also realized that we forgot to deal with the "origin" field, so I added that to all endpoints that create a new endorsement.

Halfak renamed this task from Write full specification for the Jade API to Implement a MW API module for interacting with Jade entities.Aug 6 2019, 7:57 PM

Hey @Halfak -- I'm cleaning up some existing code and seeing that talk pages were included for "Judgements". Is this still valid for "Proposals"?

Talk pages should be included at the Entity level.

Change 532471 had a related patch set uploaded (by Accraze; owner: Accraze):
[mediawiki/extensions/Jade@master] (WIP) Implement api modules

https://gerrit.wikimedia.org/r/532471

Change 536659 had a related patch set uploaded (by Accraze; owner: Accraze):
[mediawiki/extensions/Jade@master] (WIP) Implement api modules

https://gerrit.wikimedia.org/r/536659

I updated P8830 to include warnings for when the actions is a no-op.

I talked to @EvanProdromou about getting some review for this. He said that he could do some design review and maybe someone from his team could do the code review for us. As I understand it, we're very close to having a complete patchset for review. We're reaching out now because it's going to be a *big* review so we want to get it on Platform Engineering's radar.

@ACraze, could you let us know what bits are ready for review right now? Alternatively, we could have @EvanProdromou review the higher level API description (see P8830) in the meantime if that still reflects what was implemented.

@Halfak API modules are done and should be ready for review. The only things left are codesniffer cleanup, improving comments and fixing a small bug related to warnings, all of which should be done by EOD.

Alright, I finally got the Jenkins build passing and have moved the task to the Review column on the current workboard.

The initial patch was abandoned, so the correct patch to review is this one:
https://gerrit.wikimedia.org/r/#/c/mediawiki/extensions/Jade/+/536659/

Change 536659 had a related patch set uploaded (by Accraze; owner: Accraze):
[mediawiki/extensions/Jade@master] Implement Api modules

https://gerrit.wikimedia.org/r/536659

@Halfak et. al., I'm looking over the documents now. It looks like @Anomie is giving code review on the patch set, which is great

Did you consider using MCR instead of a separate namespace for storing the annotation data? It seems like a prime candidate for MCR, keeping all of the annotation data together with the page.

yes. It's an old discussion and there is a host of reasons why it is a bad idea. E.g., we're tracking structured data at the level of a diff.

Change 536659 had a related patch set uploaded (by Accraze; owner: Accraze):
[mediawiki/extensions/Jade@master] Implement Api modules

https://gerrit.wikimedia.org/r/536659

Adding todos and etherpad link from the team demo:

https://etherpad.wikimedia.org/p/jade_api_demo

Todos:

  • We need valid json in examples (i18n/api/en.json).
  • The revision comment for jadecreateandendorse should include the labeldata.
  • The first proposal should always be marked as the "preferred" label. There should always be one perferred label per facet unless a facet has no labels.
  • Documentation for setpreference should use the word "consensus" and "best".

@ACraze and I talked and we agreed about dropping action=query&list=jadegetlabels

Change 536659 merged by jenkins-bot:
[mediawiki/extensions/Jade@master] Implement Api modules

https://gerrit.wikimedia.org/r/536659