#ktistec 206 hashtags

Todd Sundsted
Release v3.11.0 of Ktistec

Despite the fact that a shared inbox is an optional actor endpoint, some servers assume Mastodon and deliver to /inbox instead of the actor's inbox. Okay, fine. This release of Ktistec includes support for shared inboxes.
🖐️🎤

Here's the full changelog:

Added

  • Accept inbound activities at a shared inbox.
  • Bound the time an inbound activity spends fetching remote objects.
  • Collapse long posts behind a generated summary.

Fixed

  • Keep a repeat follow request from ignoring the response already sent.
  • Fix poll's closed namespace, and treat closed and endTime interchangeably.
  • Remove geometry adjustments from the highlighted CSS class.

Changed

  • Be more liberal with the timestamp formats accepted.

My current passion project is the Ktistec feed deck—multiple, parallel panes in the same window, each displaying an algorithmic feed. It will be in usable shape in time for the next release.

#ktistec #crystallang #activitypub #fediverse

Todd Sundsted

The culmination of my recent work on algorithmic feeds is a #fediverse feed reading machine for all of the topics I care about.

Image of an ultrawide monitor showing the Ktistec feed deck across six feeds.

#ktistec

Todd Sundsted
Release v3.10.0 of Ktistec

The last two releases of Ktistec added backend and frontend support for algorithmic feeds. This release adds polish and links it into the navigation alongside posts, drafts, and bookmarks.

Algorithmic feeds are feeds that include (and exclude) posts with certain keywords, hashtags, and mentions. They are built on top of the materialized views that I introduced a few months ago. And they're fast!

The implementation will evolve toward something that looks like Mastodon's advanced web interface, Misskey antennas, or Friendica channels.

Here's the full changelog:

Added

  • Link to feeds index page from secondary menu.
  • Garbage collect abandoned feed drafts and orphaned feed state.
  • Backfill feeds with historical posts.

Fixed

  • Quote post request, authorization, and release fixes.
  • Recognize a swipe anywhere in the image viewer.

Changed

  • Feed editor usability improvements.
  • Bust the asset cache when a bundle's contents change.

I'm currently deep in adding shared inbox support. A few servers insist on delivering to /inbox (whether or not Ktistec actors advertise a shared inbox).

#ktistec #crystallang #activitypub #fediverse

Todd Sundsted

i just released it and i'm already pretty happy with #ktistec hashtag/mention/keyword feeds. i created an "ActivityPub Talk" feed and i have most/all ActivityPub/Fediverse/FEP/etc. etc. etc. talk in one place.

Todd Sundsted
Release v3.9.0 of Ktistec

I shipped back-end support for algorithmic feeds in the last release. In this release I shipped front-end support. The feature needs testing and polish, so it's still not possible to navigate to the feeds editor, but if you know where to look, you can try it 😉.

"Algorithmic feeds" currently means support for custom hashtag, mention, and keyword feeds (e.g everything that mentions "#fediverse" and "#activitypub" but not "x" or "facebook").

Here's the full changelog:

Added

  • Front-end support for user-defined algorithmic feeds.
  • Allow editing optional properties on published posts.
  • Support undoing a dislike.

Fixed

  • Handle concurrent duplicate inbox delivery.
  • Don't apply custom themes on the drafts and posts pages.
  • Adapt duration units in thread analysis.
  • Restore the spinning loader.

Changed

  • Restrict theme overrides to color and reduce reliance on !important.
  • Render the homepage description in a basic segment.

Removed

  • The deliver_to state and the recipients fallback.

In the next release, algorithmic feeds get wired into the navigation!

#ktistec #crystallang #activitypub #fediverse

Todd Sundsted
Release v3.8.0 of Ktistec

There are two significant new additions in release v3.8.0 of ktistec.

First, the actor cards on the followed/following pages show relevant actor status. On the followed page, it tells you how long it has been since that actor published an activity (create, announce, like, etc.) that was sent to your server. It's a proxy for how active they are (or are not). On the following page, it tells you how long it has been since you have been able to send to that server. It's a proxy for whether that server is reachable or that actor is still alive.

Second, the backend for user-defined algorithmic feeds is in place, along with a keyword/hashtag/mention feeds implementation. You can't set up a feed via the user-interface, but the feeds work if you set one up directly in the database—which is how I've been previewing them. I plan to release the frontend next week.

Here's the full changelog:

Added

  • Display activity status on actor cards.
  • Back-end support for user-defined algorithmic feeds.
  • Apply community-relayed moderator deletes received as a Group's wrapped Announce.
  • Follow a web page's rel="alternate" link when searching.

Fixed

  • Avoid loading entire has_many collections when constructing child records.
  • Evaluate the same-origin fetch gate against an embedded node's own identifier.
  • Accept a delete of an uncached object or actor without verification.
  • Catch MIME::Multipart::Error in local file-upload handling.
  • Map malformed request-body parse failures to Bad Request.

#ktistec #crystallang #activitypub #fediverse

Todd Sundsted

the backend for ktistec algorithmic feeds just landed in commit 627c9292.

it's a proof-of-concept implementation of hashtag-mention-keyword feeds popular in other servers with any/all/none clauses—not very algorithmic but it gets the plumbing right and tested. it builds on top of the materialized views support i implemented a few releases ago.

#ktistec #fediverse

Todd Sundsted
Release v3.7.0 of Ktistec

I started to work on algorithmic feeds but was side-tracked by interoperability work. No complaints. It turned out to be a productive detour.

Here's the full changelog for release v3.7.0 of Ktistec:

Added

  • Support FEP-2c59: Discovery of a Webfinger address from an ActivityPub actor.
  • Support ActivityPub Update activities for actor profile changes.

Fixed

  • Disambiguate reblog IDs from status IDs. (fixes #151)
  • Correct the quote_policy mapping to public/nobody values.
  • Ignore malformed pagination parameters instead of raising.
  • Treat "cannot be reconnected" errors as connection failures.
  • Infer a media attachment's type when mediaType is missing.
  • Faster, case-insensitive, actor username lookups.
  • Faster statuses_count using an approximate count.

Changed

  • Resolve JSON-LD contexts by matching their digest against a bundled copy.

The first version of algorithmic feeds won't be very algorithmic—it will let you create a feed that filters by keywords, hashtags, and mentions. That covers a lot of ground for me personally, and lays the groundwork for future enhancements.

#ktistec #crystallang #activitypub #fediverse

Todd Sundsted
Release v3.6.0 of Ktistec

It is said that there are only two hard things in computer science: cache invalidation and naming things. The story goes: you have something that is expensive to compute, so you compute it once and then you cache it and use the cached value in the future. But the inputs to that computation change, and so the cached value grows stale. You have to decide when and how to recompute that value.

In Ktistec, presenting accurate tag counts is expensive because not every tagged post counts. Posts are deleted, actors are blocked. My own drafts don't count, but when they're published they do. A post tagged with the same hashtag more than once, must count as one. And tag cardinality is not uniform: #3dprinting has hundreds of thousands of posts, others have one or two. Even with indexes, there is no single query that counts all cases in an acceptable amount of time.

So I reached for a cache, counted once and then cached the count. Because I didn't want to maintain adjustments from every place in the code that changed something that touched the count, I settled for eventual consistency and recomputed counts after every server restart.

As it turns out, that's not good enough. On a server with reasonable traffic, an event that affects some tag's count happens every few hours. Days or weeks later there is significant drift. Worse, the implementation didn't recompute on first read, it recomputed on first write (a new tagged object arrives).

This release fixes all that. Counts are still eventually consistent, but all counts are recomputed in a regular background task, so they really are eventually consistent, and care was taken in constructing the query to minimize database (read) locking to ~100-200msec.

Is it better? Yes! Is it perfect? Probably not. Cache invalidation is hard.

Here's the full changelog for this release:

Added

  • Background task to reconcile tag statistics.

Fixed

  • Prevent model hook callbacks from interleaving.
  • Add spacing between content and the sticky footer.

Changed

  • Replace Semantic UI with Fomantic UI.
  • Cache the PURL and GoToSocial JSON-LD contexts.
  • Reduce database lock time when reconciling tags.
  • Block npm dependency install scripts.

Removed

  • The unused idx_relationships_type database index.

In the next release, I'm going to fix a few bugs in the Mastodon-compatible API. These require an internal redesign, so I've held off until a few other things were out of the way. And I'm turning my attention to reading and better tools for surfacing and finding interesting content.

#ktistec #crystallang #activitypub #fediverse

Todd Sundsted

I need to use a prefix to namespace status IDs vs. boost IDs in the #ktistec Mastodon-compatible API. In Mastodon, a boost is just a status and they share the same ID namespace. Ktistec predates its Mastodon-compatible API, so statuses and boosts are maintained in different tables. I wanted to use an emoji (✍️ vs. 📣) to distinguish them, but that breaks too many clients.

Shame...