i
Guide to Kastalia KMS DDH ()


Guide to Kastalia KMS

This guide is organized into several sections, each approachable independently: a brief introduction to the core ideas (Brief Introduction), the project's own path and motivations (Path to Kastalia), how the system is built on the server side (Backend) and in the browser (Frontend), a catalogue of available Templates, the vocabulary of Predicates that knots use to relate to one another, and the free-form Attributes a knot can carry.

Start wherever your curiosity points you -- the graph, true to its own philosophy, has no single correct entry point.

About this Guide

This file was created for the benefit of all AIEDucators, teachers, students, developers and parents wanting to use Kastalia Knowledge Management System (KMS) creation of their own knowledge graphs, archives of more complex curricular and/or meta-curricular structures.

Brief Introduction to Kastalia KMS

Kastalia Knowledge Management System, or simply ``Kastalia KMS'', is a system for collaborative web-publishing, data-management and archivation of structured information in a form of a so-called ``knowledge graph''.

Kastalia's knowledge graph (KG) is composed of things - also called ``knowledge units'' or ``knots`` - and relations between things - also called ``bounds''.

Diverse combinations of ``knots'' and ``bounds'' can be obtained by executing different kinds of ``templates'', ultimately providing ``views'' which end up in the browser of a human user.

To the one who understands it and masters it, Kastalia KMS is a strongly generative system providing theoretically infinite flexibility in both content structuration as well as interface design.

Graphs

A graph, in the mathematical sense, is simply a set of nodes together with a set of edges connecting pairs of nodes. Kastalia treats its entire universe of discourse as one big graph: every stored unit of meaning is a node (Kastalia calls it a knot), and every stated relation between two units is a directed, labelled edge (a bound).

Unlike a tree, a graph permits any node to be reached from many different directions -- the same knot can simultaneously be the child of one category, a member of a group, the illustration of another knot, and the translation of yet another. This is precisely what lets Kastalia model real knowledge, which is rarely a strict hierarchy.

Knowledge graphs

A knowledge graph is a graph whose nodes and edges are meant to be interpreted, not just traversed: nodes stand for entities or ideas, and edges carry a specific predicate (a verb, in effect) that says exactly how the two nodes relate -- is_parent, translates, illustrates, and so on.

Kastalia KMS is, at its core, a general-purpose engine for building, editing and rendering exactly this kind of graph. It does not presuppose any particular domain: the same knots/bounds substrate underlies a university course, a glossary of linguistic terms, an archive of spoken recordings, or a tree of philosophical arguments. What differs between these uses is only which predicates get used, and which template is chosen to turn the raw graph into something readable.

Knots and bounds

The two fundamental tables of Kastalia's database are knots and bounds.

A knot is a single addressable unit of content: it has a unique knot_id, a knot_name (its path-like, human-readable label), a knot_content (free text, typically light HTML, such as the page you are reading right now), and a set of free-form attributes (an open-ended key-value store -- see the Attributes section of this guide).

A bound connects two knots -- a sub(ject) and an obj(ect) -- through a predicate that names the relation between them (see the Predicates section). Bounds also carry an ord (ordering, used whenever children/items need a stable sequence) and a bound_creator (who asserted the relation).

Everything visible anywhere in Kastalia -- a course, a presentation, a glossary entry, a recording -- is ultimately just some knots and the bounds between them, read out through a template.

Templates and views

A template is the piece of code that decides how a given knot (and, typically, its neighbours in the graph) gets turned into an actual page a human can read. Kastalia uses Template::Toolkit (Perl's TT) for this: each template is a .tt file living under views/, free to query the graph however it needs and to render the result however it likes.

The same knot can, in principle, be rendered by several different templates -- a lecture knot might look like a slide deck under mainframe, a flat document under knot (the default), or a node in a force-directed diagram under arbre. Which template applies is usually decided by the knot's own template attribute, though some domains additionally define a fixed canonical template that every .knot-style URL on that domain gets routed through regardless (see domain_template in config.yml).

The resulting rendered page is called a view.

Predicates

Every bound needs a predicate: a short, fixed vocabulary word that says exactly how its subject knot relates to its object knot. Kastalia constrains this vocabulary deliberately -- predicates live in a proper Postgres ENUM type, not a free-text column -- so that a graph query can rely on a closed, known set of relation kinds rather than accidentally-inconsistent free text.

This short mention is just a pointer: the full catalogue of predicates, with one knot describing each, lives in its own section of this guide (see Predicates, further down).

Path to Kastalia

Kastalia did not appear out of nowhere. This section gathers the three threads that, braided together, led to the system as it exists today: the philosophical commitments that shaped its design (Philosophy), the fictional and speculative works that fed its imagination (Fiction), and the plain factual record of how the project actually unfolded over time (History).

Philosophy

Kastalia is named after Hermann Hesse's Castalia, the walled province of pure intellectual play in The Glass Bead Game -- a deliberate signal that the system is meant to treat knowledge not as a pile of documents to be filed away, but as material for a game: something to be combined, recombined and played with across disciplines.

Technically, this philosophical stance shows up as a refusal to commit to any one fixed schema. Where most content-management systems bake a particular domain's structure into their database (a blog has posts and comments; a course platform has courses and lessons), Kastalia's knots and bounds commit to almost nothing -- any knot can, in principle, stand in any relation to any other. The cost of that freedom is that the system gives you very little for free; the benefit is that it never tells you no.

Fiction

Beyond Hesse's Glass Bead Game, Kastalia's design draws loosely on a handful of other fictional and speculative treatments of knowledge-as-structure: Borges' Library of Babel and his Garden of Forking Paths (both meditations on combinatorial, non-linear texts), and Vannevar Bush's non-fictional but visionary 'memex' -- an imagined machine for associative, trail-following reading that anticipated hypertext by decades.

None of these are literal blueprints. What they share, and what Kastalia tries to inherit from them, is the idea that a body of knowledge is better modelled as an explorable, richly cross-linked space than as a shelf of separately bound books.

History

Kastalia grew, over several years, out of earlier and smaller tools built for recording, annotating and replaying spoken language data -- the is_uttered_as, illustrates and translates predicates still carry traces of that origin. Over time the same knots/bounds substrate proved general enough to also carry course material, presentations, glossaries and personal archives, and the system was generalized accordingly.

Today Kastalia KMS powers several independently themed sites (baumhaus.digital, udk.ai, wizzion.com and others) from the very same underlying graph -- each domain simply renders a different canonical slice of it, through its own domain_template.

Backend

Kastalia's backend is a Perl application built on the Dancer2 web framework, storing its graph in PostgreSQL. This section describes the two layers that matter most: the SQL core (the actual table/enum design behind knots and bounds) and the PERL Core (the routes and helper functions that read and write it).

SQL core

Two tables carry almost the entire system: knots(knot_id, knot_name, knot_content, attributes hstore) and bounds(bound_id, sub, predicate, obj, ord, bound_creator).

attributes is a Postgres hstore column -- an open-ended set of key/value string pairs -- rather than a fixed set of typed columns. This is what lets a knot carry wildly different metadata depending on what it's being used for: a presentation knot might have ogg_url and presentation_timeline; an image knot an img_url; a person knot an age or voice. No schema migration is needed to introduce a new attribute -- any route can simply start writing a new key.

predicate, by contrast, is a proper Postgres ENUM type, not a free string -- a closed, explicit list of the relation kinds the graph currently understands (is_parent, contains, is_member, is_uttered_as, illustrates, translates, echoes, is_linked, and a handful of others). Extending the vocabulary means explicitly adding a new value to that enum (ALTER TYPE predicate ADD VALUE ...) -- a small deliberate act, not an accident of someone typing a slightly different string.

PERL Core

The application's Perl code lives under lib/Kastalia/. Main.pm defines almost every HTTP route -- what URL does what. Core.pm, TT.pm, SelectorQueries.pm and API.pm have no package statement of their own: they are require'd straight into Main.pm's namespace, so every helper function they define (addKnot, addBound, addAttribute, the various graph-query helpers used by templates, and so on) is directly callable, unqualified, from anywhere in that merged namespace -- effectively one large shared toolbox rather than several separate modules. User.pm is the one exception that keeps its own package Kastalia::User, for the LDAP-backed account/login logic, while still sharing the same Dancer2 app context.

Dancer2 itself handles routing, sessions (backed by Memcached) and the Template::Toolkit rendering described in the Frontend section.

Frontend

What a visitor actually sees is produced entirely by server-rendered Template::Toolkit templates -- there is no separate client-side application framework. This section covers Template Toolkit's role in Kastalia specifically; the companion Templates section of this guide catalogues the individual .tt files and what each one is for.

Template Toolkit

Kastalia configures Template::Toolkit with custom delimiters -- <% and %> instead of TT's usual [% and %] -- and with ANYCASE enabled, so template directives are not case-sensitive. Templates live as .tt files under views/, and are free to call back into the shared Perl namespace described in the Backend section to fetch whatever graph data they need (a knot's children, its echoes, its illustrations, and so on) before rendering.

Most pages share common fragments via an INCLUDE directive pointing at "layouts/..." -- the flash-message banner used across the site, for instance, lives in a single shared layout rather than being duplicated into every page template that needs it.

Templates

A non-exhaustive sample of the templates this system actually uses, to give a sense of the range:

knot is the plain default view, rendering a knot's content and its children as an ordinary document.
mainframe turns a knot and its children into a live, broadcastable slide deck, with optional audio narration, a classroom-cast mode, and cross-referenced-knot preview-on-hover.
reveal2 is an older slide-deck template built directly on reveal.js.
semester renders a whole course's session list, including a 'live' badge for whatever is currently being cast.
play and read are built around spoken-word recordings linked via is_uttered_as and illustrates.
arbre renders a knot's neighbourhood as a graph diagram.

Separately, several domains each define their own fixed canonical template (console, treehouse, arena, atlas, and so on) that every .knot-suffixed URL on that domain uses regardless of the knot's own template attribute -- see domain_template in config.yml.

Predicates

is_parent

Subject is an umbrella term / hyperonym / supertype of the object (hyponym).

is_parent is the very first predicate implemented and used in Kastalia and for many years, it has been used to denote any kind of relation between super- and sub- ordinated categories.

contains

Used when object of the bound is contained in the subject knot.  On the first sight, contains predicate is confusingly similar to is_parent
 
However, while objects of ``is_parent'' relations can be themselves ``non-terminal'' - that is, they can themselves be subjects of other ``is_parent relations'', objects of bounds predicated with contains should always be terminals (i.e. should not be subjects of other contains relations).

Implemented to allow for possibility to have one and same recording included in several distinct container knots. Currently used mostly by the play template.

is_member

Subject (meronym) is a part of object (holonym). Similar to is_parent and contains predicates but with flipped order of parameters.

Used mainly by HMPL and BDLP templates.

is_uttered_as

Specifies relation between knot containing text T and knot containing speech recording of one single act of uttering T.

Used by templates play, read and paaren.

illustrates

Predicate of type "illustrates" specifies relation between subject knot I whose attribute img_url contains URL of illustration of the object knot.

Used by practically all templates where usage of N-to-1 illustrations is appropriate (e.g. read / play / paaren).

translates

Subject knot is translation of the object knot.

Attributes

Attributes are the free-form, per-knot metadata stored in the attributes hstore column. A handful of names recur often enough across templates to be worth knowing: template (which .tt file should render this knot), public (whether anonymous visitors may see it), creator and epoch (who made it and when), img_url (an illustration), ogg_url and presentation_timeline (audio narration and its synced slide-navigation events, used by mainframe), and voice/age/gender/motherlang/consent (speaker metadata for recordings).

Because attributes is schemaless, nothing stops a template from inventing its own attribute name for its own purposes -- these are simply the ones already in wide use across the existing templates.