Page MenuHomePhabricator

Build infrastructure to track counts of qualifying edits for the Suggested Edits feature
Closed, ResolvedPublic

Description

The Android team needs a means of maintaining counts of qualifying edits with various characteristics per user. A WIP prototype is currently implemented as a MediaWiki extension hooking into the PageContentSaveComplete event to update counts as appropriate.

Counts will be maintained in a new extension, WikimediaEditorTasks.

Edit counts to maintain:

  1. For the title descriptions task list:
    • To unlock: 5 logged-in in-app description edits + 48h waiting period complete
  1. For the image captions task list:
    • To unlock: 50 logged-in in-app description edits + 48h waiting period complete

On revert (of ANY edit by the user): reset the counter for the next stage to unlock to 0

Open questions

  • How should we handle local descriptions on enwiki?

Event Timeline

Mholloway created this task.
Mholloway renamed this task from Build an API to track counts of qualifying edits for the Android App Editor Tasks feature to Build a MediaWiki extension (+ API module) to track counts of qualifying edits for the Android App Editor Tasks feature.Jan 3 2019, 3:49 PM
Mholloway updated the task description. (Show Details)

Getting this out of an email thread and into Phab where it belongs.


I went ahead and prototyped this, and the result is at https://github.com/mdholloway/EditCounts. No vagrant role yet, so you'll have to manually clone it into your mediawiki/extensions directory and add a wfLoadExtension( 'EditCounts' ); line to LocalSettings.php. After installing, you'll need to run maintenance/update.php to add the DB tables.

Most of the business logic lives in the abstract Counter class. To add different counters for different edit types, simply subclass Counter, add constants defining a couple of DB property names and the target number of edits to unlock the goal, and implement onEditSuccess() and onRevert() to specify the desired behaviors on each of those events. An example implementation is given in src/WMF/WMFTestEditCounter.php. This is also where the custom filtering logic will be defined (for example, to count only edits on Wikidata), but that's not quite firmed up yet, so there's not much point to creating different concrete implementations at the moment; as of now this is just a simple edit counter.

Right now I have the active counters specified by implementing the ICounterConfig class and returning them in getDefinedCounters() (see src/WMF/WMFCounterConfig.php). This should probably actually happen in the extension configuration. (Update: Counters to enable are defined in the extension config.)

To deal with storage I just went ahead and created two extremely simple DB tables: edit_counts and edit_counts_achievements. edit_counts is basically a generic key-value store, but only accepts integers as values. An entry is added to edit_counts_achievements when a user unlocks an achievement.

The extension hooks into PageContentSaveComplete, just as Echo does, to respond to edits and update counts and achievements. I haven't tested the rollback action yet, but I know it works correctly for edits and undo actions. (Update: handles rollbacks.)

Dao.php does what you'd expect.

The extension exposes an API module, editcounts, via w/api.php?action=editcounts, which returns results in the following proposed format:

{
    "editcounts": {
        "counts": {
            "test_app_edits": "5",
            "test_edits": "5"
        },
        "achievements": [
            "test_app_edits_feature_unlocked",
            "test_edits_feature_unlocked"
        ]
    }
}

No tests yet beyond what was provided in the BoilerPlate extension, sorry. (Update: has tests.)

If this basic approach seems sound, then we can work on getting set up in Gerrit and get this stuff properly reviewed. If not, let's talk about what needs to be done differently.

Mholloway renamed this task from Build a MediaWiki extension (+ API module) to track counts of qualifying edits for the Android App Editor Tasks feature to Build a MediaWiki extension (+ API module) to track counts of qualifying edits for the App Editor Tasks feature.Jan 8 2019, 7:40 PM

Hey, you might want to consider a more specific extension name than 'EditCounts' - we already have an extension:Editcount, which shows, well, editcounts and general statistics, but it sounds like this is something a lot more specific/complex than that. Perhaps a more specific name to better reflect what this is actually doing and is for would be less confusing, especially in the long run? What kind of editcounting is this? What is being done with the edit count, or is it intended for?

From what I'm seeing here, this seems like something especially intended for reuse by other things, so it would be good if it had a name that would lead to better discoverability by future and third-party developers who would be able to put it to use as well.

@Isarra Thanks, I had been wondering if "EditCounts" was a bit too generic. "QualifiedEditCounts" is another candidate I had in mind. "EditCounts" is basically a naming collision with the extension you mentioned (thank you!) so it'll have to change to something else.

I am indeed trying to keep this pretty generic: basically "if this edit meets <criteria defined in/coded into counter> then <increment/decrement/something else>"...

Maybe something like gamificationtracking/backend or such.... I do like QualifiedEditCounts as it does rather better describe just what it's doing, except the meaning of 'qualified' is a bit unclear out of context. Is there another word that might also work for that while still qualifying the sort of edit counting this is?

Or go with some sort of CriterionTracker, DefinedCriteriaBasedIncrementer, or something else based on that very nice concise description there.

For that matter, is it even going to just be edits, or will it potentially include log actions and such, too? Maybe consider that too.

Hmm, I suppose it could and possibly should be extensible enough to count anything. Maybe SpecialPurposeCounters...

ActionCounters, since it's for the edit action feed?

I'm actually trying to keep the architecture as general-purpose as possible, and have the edit action feed supporting stuff as one consumer.

I'm sort of fond of ConfigurableCounters.

@Charlotte As described above I have been planning on needing two different counters for the first two stages of the edit action queue: one to track only description edits, and another to track description edits plus image caption edits. Now I'm no longer sure this makes sense: do we really need to restrict the first 5 edits for unlocking the description edit queue to only description edits and not image caption edits? I'm happy to track both separately if there's a product need for it, but otherwise, using a single counter for which both actions qualify would make things on the backend just a little bit simpler and therefore better.

Some questions about future usage of the scoring component that might influence architecture choices:

  • Using MediaWiki (or more generally server-side) storage means that 1) different clients cannot have different scores or different achievement thresholds; 2) the feature cannot be extended to anonymous users (e.g. for getting user sign up after they made N edits). Those seem like unlikely use cases, but just to confirm, are we OK with excluding them?
  • Wikidata and Commons are central projects but presumably at some point there will be task types which can be done on any Wikipedia (or some other sister project). Will there be a need to track scores in some other way than separately per wiki? (E.g. total number of Wikipedia edits.)
  • Is it important for scoring to be consistent, in the sense that old points use the same logic as new points? (Ie. if the scoring logic changes, say reverts are changed to decrease score by 1 instead of resetting to 0, is it important for analytics or A/B tests or whatever to apply to changes to scores accumulated in the past?)

It appears that the App Editor Tasks feature introduces the concept of per-language user rights to make microcontributions (T207684), and I learned yesterday that the team needs a place to store the set of languages in which a user has been deemed qualified.

Fundamentally, what it seems like they need is a place to persist arbitrary bits of feature-specific data per user.

The right place for something like that would seem to be https://www.mediawiki.org/wiki/Extension:MobileApp, whether in purpose-built tables per feature, or a generic key-value store. The latter would have the virtue of allowing the app teams to iterate or change plans in an agile way without necessarily requiring RI involvement for each change.

I'll give these my best shot, though they get into product territory.

Some questions about future usage of the scoring component that might influence architecture choices:

  • Using MediaWiki (or more generally server-side) storage means that 1) different clients cannot have different scores or different achievement thresholds; 2) the feature cannot be extended to anonymous users (e.g. for getting user sign up after they made N edits). Those seem like unlikely use cases, but just to confirm, are we OK with excluding them?

AFAIK these use cases are not on the agenda, but that's for @Charlotte to confirm. That said, I think we could actually do something like set up different counters for the iOS and Android apps and filter for each based on tag summaries (though I don't know why we would do that).

  • Wikidata and Commons are central projects but presumably at some point there will be task types which can be done on any Wikipedia (or some other sister project). Will there be a need to track scores in some other way than separately per wiki? (E.g. total number of Wikipedia edits.)

I've actually been intending for these counters to be fundamentally universal, with per-wiki filtering happening (if necessary) in the Counter implementations.

  • Is it important for scoring to be consistent, in the sense that old points use the same logic as new points? (Ie. if the scoring logic changes, say reverts are changed to decrease score by 1 instead of resetting to 0, is it important for analytics or A/B tests or whatever to apply to changes to scores accumulated in the past?)

I've been assuming consistency is not needed; but by creating new Counters with distinct keys for any scoring logic changes, we could ensure that counts following different scoring logic are distinguishable.

The right place for something like that would seem to be https://www.mediawiki.org/wiki/Extension:MobileApp, whether in purpose-built tables per feature, or a generic key-value store. The latter would have the virtue of allowing the app teams to iterate or change plans in an agile way without necessarily requiring RI involvement for each change.

There was some discussion about a key-value store in T128602: RFC: Backend for synchronized data from Wikipedia mobile apps (for a while it was envisioned as the backend for prototyping reading lists). Probably worth its own extension, if it is to be made generic.

@Tgr Yes, T128602 is essentially what I had in mind. Putting a version of it in MobileApps would in theory be a way of making it less controversial, to the extent it's controversial at all (actually not very, as I recall from the RFC meeting). But I think you're probably right that it deserves its own extension.

Which do you think is the better approach for the requirements here in general? One-off, special-purpose tables in the MobileApp extension, or generic key-value?

Or, considering that the infrastructure needs for this feature continue to expand as we speak, maybe it's worth collecting everything in its own extension at this point, rather than putting some pieces here and others there.

@Tgr Could the recently-created ConfigurableCounters extension just be renamed and repurposed (since it's currently basically empty)? Not sure how the picture looks on the Gerrit admin side.

IMO having separate extensions for the pieces of functionality that are conceptually unrelated (counters, a task queue, a key-value store) makes sense. It's more work and slightly more risky (in the sense that if it turns out there needs to be a stronger interaction between them, it's a bit more effort to rearrange things if they were separate extensions initially) so it's fair to take the easier route; but they do seem useful in general (both as MediaWiki extensions and as Wikimedia functionality available to volunteers doing their own things).

As for generic k/v store vs. MobileApps features, the trade-off there is providing useful generic functionality (which people currently abuse the user settings API for) vs. potentially having to deal with it being abused. (I don't foresee much reason for people to abuse it, but then no one saw the WP0 file upload mess coming either.) I'd go for the more generic version, personally. I think the abuse potential is there either way, if a little less obvious / more visible.

@Tgr Could the recently-created ConfigurableCounters extension just be renamed and repurposed (since it's currently basically empty)? Not sure how the picture looks on the Gerrit admin side.

I believe renaming repos is not a big deal as long as nothing uses them; renaming in Gerrit is a single admin action, plus you need to change the name in CI. It only becomes very problematic when the extension is deployed and/or used by third parties. @Jdforrester-WMF probably knows more about this, IIRC Editing went to a lot of trouble to rename some things.

Yeah, renaming is pretty simple if no-one is using it yet.

The standalone extension providing a generic, authenticated key-value store is appealing in principle. I do worry about the potential for abuse, and on a related note, the potential that we'd run into (reasonable) 11th-hour objections to deploying it to production and thereby set back the project timeline. That said, if there aren't any gotchas I'm naively overlooking, it shouldn't take a terribly long time to implement, and I'm sure we could find other places to store the values in question if problems do arise. I'll have a quick chat with Joa about it.

As a last resort, the data could always be stored as userjs-* user settings. The limitation there (apart from being an ugly hack) is that the data needs to be small, but AIUI we are just talking about a few numbers here.

Gauntlet thrown: https://github.com/mdholloway/AuthenticatedKeyValueStore

I requested a repo in Gerrit, and we can do code review there for this, too, but thought I'd get a head start.

OK, after thinking this through some more, here are some decisions re: the above. Please let me know if you strenuously object.

  • ConfigurableCounters will be renamed to AppEditorTasks and will be purpose-built for this feature. This project and its timeline being what they are, there isn't the time to try to force the specific product requirements here into the form of a generically useful "counting things" extension. (@Jdforrester-WMF, do you have the power to make this change happen in Gerrit? I can patch integration/config.)
  • The generic authenticated key-value work will be deprioritized relative to the rest. If there isn't time to finish it before launch time, and we end up having to store user "levels" somewhere else (presumably in special-purpose tables in AppEditorTasks), so be it. AuthenticatedKeyValueStore will most likely live on as a 10% time project.

OK, after thinking this through some more, here are some decisions re: the above. Please let me know if you strenuously object.

  • ConfigurableCounters will be renamed to AppEditorTasks and will be purpose-built for this feature. This project and its timeline being what they are, there isn't the time to try to force the specific product requirements here into the form of a generically useful "counting things" extension. (@Jdforrester-WMF, do you have the power to make this change happen in Gerrit? I can patch integration/config.)

No, renaming repos in gerrit essentially breaks things. Just create a new repo and flag the old one for closing.

@Jdforrester-WMF Requested the new repo. How do I flag the old one for closing?

Say the name @MarcoAurelio three times and they'll swoop in and get it done. ;-)

Hi @Mholloway - I didn't see your comment about the types of editing above. The only thing we will allow users to do as anons and/or without unlocking the feed is adding descriptions, not image captions. Image captions have to be unlocked later, as a separate level.

@Charlotte Aha—that makes sense. Thanks for clarifying.

Mholloway updated the task description. (Show Details)
Mholloway updated the task description. (Show Details)
Mholloway updated the task description. (Show Details)
Mholloway renamed this task from Build a MediaWiki extension (+ API module) to track counts of qualifying edits for the App Editor Tasks feature to Track counts of qualifying edits for the App Editor Tasks feature.Feb 24 2019, 6:17 PM
Mholloway renamed this task from Track counts of qualifying edits for the App Editor Tasks feature to Build infrastructure to track counts of qualifying edits for the App Editor Tasks feature.
Mholloway renamed this task from Build infrastructure to track counts of qualifying edits for the App Editor Tasks feature to Build infrastructure to track counts of qualifying edits for the Suggested Edits feature.Mar 13 2019, 7:53 PM