This was split off from {T179849}: for now, we’ll start out with caching the results in memcached. That will already require us to solve the problem of invalidation, and migrating to the database for {T180582} (see [this comment](https://phabricator.wikimedia.org/T179849#3770891)) can then be done in the future. (Probably not by actually moving results from memcached to the database but just by starting to write to and read from the database instead.)
Preliminary breakdown:
- [ ] extract result formatting (`CheckResult` → JSON) out of the `CheckConstraints` API class, because the API probably shouldn’t know about caching
- [ ] track entities that should be considered when checking whether a cache result is still valid (checkers for inverse, symmetric and target requires claim add the target entity, current entity is implicitly added)
- [ ] store result and tracked entities in object cache
- [ ] read result from object cache and check whether it’s still fresh
- [ ] remove result from object cache on `ArticlePurge` hook