Todd Sundsted
Algorithmic Feeds: The Data Exchange
The previous two posts (here and here) in this series on algorithmic feeds introduced the built-in criteria judge and external custom judges. A custom judge is a script run by the Ktistec server that…

The previous two posts (here and here) in this series on algorithmic feeds introduced the built-in criteria judge and external custom judges.

A custom judge is a script run by the Ktistec server that decides whether a post is included in the feed or excluded from the feed based on data about the posts that the server provides in a temporary SQLite database.

There is a lot of data to work with (the owner is you, the feed's creator):

  • feed
    One row describing the feed being judged.
    • name : The feed's name.
    • description : The feed's description.
    • params : The feed's parameters.
  • stats
    One row. Posts per day over the last 90 days, across the authors the owner follows (confirmed only, not deleted or blocked). Authors who posted nothing in that window are left out.
    • posting_rate_q1 : First quartile.
    • posting_rate_median : The median.
    • posting_rate_q3 : Third quartile.
  • authors
    One row per author of any post in posts or referenced. 
    • iri : The author's IRI.
    • type : The actor type.
    • handle : The author's handle.
    • followers : The IRI of the author's followers collection.
    • deleted : Whether the author is deleted.
    • blocked : Whether the author is blocked.
    • followed : Whether the owner follows the author (a confirmed follow).
    • rate_7, rate_30, rate_90 : The author's posts per day over the last 7, 30, and 90 days, counting only posts the server has cached that aren't deleted or blocked.
  • posts/referenced
    posts holds the posts to judge. referenced holds the posts replied to or quoted, one level deep. Both tables have the same columns.
    • iri : The post's IRI.
    • type : The object type.
    • name : The post's name (title).
    • summary : The post's summary (content warning).
    • content : The post's content as HTML (Markdown is converted).
    • language : The post's language.
    • sensitive : Whether the post is marked sensitive.
    • published : When the post was published.
    • to, cc, audience : The addressing, as arrays of IRIs.
    • attachments : An array of {url, media_type, caption}.
    • in_reply_to : The IRI of the post this one replies to.
    • quote : The IRI of the post this one quotes.
    • thread : The IRI of the thread's root.
    • hashtags, mentions : Arrays of {name, href}.
    • labels : An array of the owner's private labels on the post.
    • author : The author's IRI.
    • deleted : Whether the post is deleted.
    • blocked : Whether the post is blocked.
    • timeline : "create" or "announce" if the post is in the owner's timeline, otherwise NULL.
    • poll : {options, multiple_choice, closed_at}, but only when type is "Question".

This data is used in the example judges shipped with Ktistec.

The polls judge builds a feed consisting of polls. It includes only posts whose type is "Question". It would be very easy to extend this judge to filter on single-choice vs. multi-choice or on polls about specific topics.

The quiet_posters judge is a little more complex. The server provides statistics on all of the actors you follow, as well as the author's posts per day over the last 7, 30, and 90 days. A post is included only if you follow its author and that author's 90-day posting rate is at or below the median, so the quieter half of your follows aren't drowned out by the noisier ones.

As you might imagine, there's a lot of value in judges built around statistics, social signals, and interactions. This is the area where I'm now putting most of my effort.

#ktistec #AlgorithmicFeed #ActivityPub #fediverse