ktistec uses sqlite as its datastore. it’s a smart idea to back up the sqlite database periodically. unfortunately you can’t just copy the database file, at least while the server is running.

this article explains how to make a backup safely, and how to set up automatic, scheduled backups with cron.


Ktistec on FediDB

hmmm... gotta add status count to nodeinfo output...


dynamic rules (configurable at run time rather than compile time) will soon be merged into the main branch of ktistec. the current rules define handling of notifications (which activities result in notifications to the user) and the timeline (which activities end up in the user's timeline).

by default, posts that mention other users but not you won't show up in your timeline. but maybe you want to see them in your timeline. now you can change the rules so that you can!

rules for handling the inbox, outbox and collections in general will be coming soon...

#ktistec #school

next up on ktistec...

i'm writing a simple tdop/pratt parser for rules, now. i've done it before for other projects, with more complicated grammars, and imo they're easier to understand and extend than lr/ll parsers. douglas crockford popularized them in a post a while back—writing a javascript parser in javascript.

#ktistec #school

status update on ktistec...

commits 831dce60 to aa608699 reimplement notifications and timeline management as declarative rules rather than procedural logic. this is the culmination of work announced a while back. here's a sample of what the code looks like now:

rule "create" do
  condition var("activity"), IsAddressedTo, var("actor")
  condition CreateActivity, var("activity"), object: var("object")
  any Mention, var("mention"), subject: var("object"), href: var("actor").iri
  none Notification, owner: var("actor"), activity: var("activity")
  assert Notification, owner: var("actor"), activity: var("activity")

rule "announce" do
  condition var("activity"), IsAddressedTo, var("actor")
  condition AnnounceActivity, var("activity"), object: var("object")
  condition Object, var("object"), attributed_to: var("actor")
  none Notification, owner: var("actor"), activity: var("activity")
  assert Notification, owner: var("actor"), activity: var("activity")

the first rule says, if an object (post) mentions the actor (you) and a notification doesn't already exist, create one. the second rule says, if someone announces (shares/boosts) an object (post) attributed to the actor (you) and a notification doesn't already exist, create one.

the implementation took three steps: 1) implement a simple, generic rules engine called school, 2) implement logic in ktistec to make it possible to expose the object model and records in the database as facts in the rules engine, 3) reimplement the rules. there was plenty of yak-shaving, too—the preceding ~15-20 commits were fixing things that were in the way. (my usual heuristic assumes 25% refactoring existing code and 75% developing new code, but in this case it was 75%/25% in the other direction.)

while not trivial, rules are easier to reason about than code. toward the end of the project i realized that i wasn't adding replies addressed to me to the timeline (they were only visible in a thread). i was able to fix that defect with a small modification to the rules.

the goal is to make rules modifiable by the user at runtime so that users can customize their ktistec instance without having to rebuild it. the next step toward that end is a simple rules definition language and parser.

#ktistec #school #crystal #nocode

if you're wondering what's going on with ktistec, i'm currently focused on creating a general purpose rules engine in crystal called school, and rewriting the internal logic using rules. ultimately adding/removing/changing rules will be something that users can do dynamically using a simple domain-specific language or user interface, and ktistec will become a highly customizable tool for connecting to the fediverse.

#ktistec #school #crystal #nocode

new project sunday... the school rules engine.

i'm going to rewrite all of the logic for handling fediverse activities in kistec as rules, and then expose a simple ui for managing those rules so that users can more easily customize their instance. want to change what shows up in the timeline? no problem!

#crystal #school #rulesengine #ktistec #fediverse

aaaaand i've tagged the v1.0.0 release of ktistec! 🎉 🎊 🥂

the last push was for greater compatibility with other fediverse servers—it took quite a bit of yak-shaving to get it done.

i also released a docker image if you want to try it out:

docker run --rm -it -p 3000:3000 toddsundsted/ktistec:latest



i've tested ktistec compatibility with:

  • mastodon
  • peertube
  • pixelfed
  • lemmy
  • write.as

many things work—follows in both directions and creating/updating notes (AKA toots, etc.)—but there's lots of room for improvement. lemmy, for example, announces activities instead of forwards activities. i'm working on 1.0, but in the next major release, i'll build server-specific extensions to handle more of these kind of issues.

i created a few issues in other repos:

and worked around a few issues that haven't quite rolled out:

and made many other concessions for compatibility.

#activitypub #ktistec

once you've seen one activitypub implementation, you've seen one activitypub implementation.

i just wrapped up a whole lot of interoperability work for ktistec. bottom line, you can't just read and implement the activitypub spec et al and expect anything to federate with your implementation. your best bet, in fact, is to doggedly copy the mastodon implementation, right down to the braces and brackets—since every other implementation is at least shooting for mastodon compatibility—and then work from there.

to be fair, about half of the fixes were arguably due to bugs in my own code. but seriously lemmy, why do you require the json-ld context to be a list, even when the context is defined by a single URL...?

#activitypub #ktistec