DR McCullochHOMESHOPABOUT

GORONWY · THE LÚRONWY–MÍHARÁE REPOSITORY

The Goronwy Codex

A self-hosted agentic AI system I orchestrated in January 2026, whose code takes its names from a Celtic myth I prompted.

The tapestry is alive with the whispers of the Sidhe, the murmurs of gatherings and the thrums that echo through the realms.README.md, line 3

Goronwy watches your computer (the browser, Google Workspace and the system itself) and sorts each event by how sensitive it is, sending the sensitive ones to a language model on the same machine and letting the general ones go to Claude or Gemini. Whatever needs your attention comes back to you as a notification on the desktop or in WhatsApp. The names come from a myth that draws on the process philosophy of Whitehead and Simondon, so schemas are Covenants, events are Lyrics, notifications are Songs and each of the myth’s four weavers has its own folders in the repository. Further down is a matrix of the 66 connections between its 27 components, which you can trace one flow at a time, followed by the source and the myth’s own glossary.

Go to the matrix

The four weavers, two of them running

Míharáe and Lúronwy have handlers and services running in the system, and every connection in the matrix further down starts in one of their components, in the shared infrastructure or at the external APIs. Éofránna and Chibuelassa have code in the repository, a context-assembly service and a retrieval transport that already searches the vector store, but their event handlers are still empty functions, so neither appears in the connectivity data. I call them the warp, the vertical threads set on a loom before any weft crosses them. Pick either of their cards to brighten the two dashed bands at the right edge of the matrix that stand in for them.

Míharáe

The Perceiver

Míharáe listens to the whispers of the future, perceiving the unspoken lyrics hidden within the tapestry.

In the code Míharáe reads what happens in the browser, in Google Workspace and on the system itself, sorts each event as sensitive, internal or general and routes it to the local model or the cloud accordingly.

handlers/miharae · services/miharae27 of 66 connections start here

Lúronwy

The Voice

Lúronwy gives voice to what Míharáe perceives. They take the whispers moving through the tapestry and shape them into something that can travel. Their songs carry across realms. What was silent becomes heard.

In the code Lúronwy turns what Míharáe found into notifications on the desktop and in WhatsApp and carries out actions in Google Workspace once you approve them, logging each one so it can be undone, though for now undoing only marks the action in the database. Syncing across devices is written, but it depends on peer-to-peer pairing that is still a stub.

handlers/luronwy · services/luronwy20 of 66 connections start here

Éofránna

The Mender

They move among frayed edges and scattered voices, drawing what is broken toward what is whole. Their presence is quiet. The mending happens anyway.

In the code Éofránna assembles context from RAG, activities and tasks into a single prompt before it reaches Míharáe. The assembly service is written and tested, but its event handler is still an empty function, so nothing in the running system calls it yet.

handlers/eofranna · services/eofrannano connections yet

Chibuelassa

The Pathway

Chibuelassa is a pathway stretched between worlds that should not touch but must. They exist only in motion. No origin, no destination—only the space between. To encounter Chibuelassa is to already be somewhere else.

In the code Chibuelassa fetches context from the vector store and other sources and passes it to Éofránna. RAG retrieval works, using the local model’s embeddings and a vector search, while the activity and task adapters still return an empty list and the event handler is an empty function.

handlers/chibuelassa · services/chibuelassano connections yet

The nine steps of the data flow

ARCHITECTURE.md lists nine steps from an activity being detected to feedback being learned from, each with its phrase in the myth. Steps three and four are dimmed because Éofránna and Chibuelassa, who own them, aren’t running yet.

  1. 1MíharáeMíharáe listens.Activity detected (browser, workspace, system)
  2. 2MíharáeMíharáe perceives patterns.Data classified (sensitive/internal/general)
  3. 3Chibuelassa · warpThe pathway between worlds.Context fetched from RAG and other sources
  4. 4Éofránna · warpDrawing what is broken toward what is whole.Context assembled and mended
  5. 5MíharáeMíharáe adjusts nodes.Routed to appropriate LLM (local or cloud)
  6. 6MíharáeMíharáe illuminates threads.Processed and analysed
  7. 7LúronwyLúronwy transforms whispers into songs.Notifications generated if actionable
  8. 8LúronwyLúronwy gives weight to connections.Actions taken if approved
  9. 9LúronwyLúronwy captures essence.Feedback collected and learned from

The tapestry as an adjacency matrix

The tapestry is a unidirectional weighted adjacency matrix. The same 27 components run down the left and across the top, each row a known that sends and each column a knower that receives, so a square where the two cross is one lyric passing from one component to the other. Its colour is the part of the system the sender belongs to and its size is the weight the table gives it, from 0 to 6. Click a button to trace a flow through the system.

Trace a flow

Colour is the sender:Míharáe (perception)Lúronwy (voice)Shared infrastructureExternal APIs

Size is the weight:1460, an empty outline

Dashed bands: Éofránna and Chibuelassa, no connections yetWhite squares and a line: the flow you’re tracing

Processing Handler sends more connections than any other component, 8 of them, and Config Repository receives the most, 14, nearly all of them components loading their settings, keys or rules. Of the 66 connections, 27 start in Míharáe’s components, 20 in Lúronwy’s, 15 in the shared infrastructure and 4 at the external APIs. Their weights run from 0 to 6 and average 3.8.

† The summary at the end of component-connectivity-matrix.md gives 28 components and 52 connections, with the Event Bus sending the most (6) and the Activity Repository receiving the most (5). The matrix here is drawn from the CSV beside it, where I count 27 components and 66 connections, with Processing Handler and Config Repository at the top.

‡ The weights in the CSV add an estimate of how often two components talk to an estimate of how much data passes between them, and they set the size of each square. The myth has a weight of its own, which the README defines as how closely illocutionary force matches perlocutionary effect, a number from 0 to 1 for how nearly a speech act lands as intended, and nothing on this page measures it. One connection has a weight of 0, Data Classifier loading its classification rules from Config Repository, and it is drawn as an empty outline.

What isn’t finished

In tapestry weaving, the warp is the set of foundational vertical threads that must be set up first, held taut on the loom, before any weaving can begin. … Without the warp properly laid, no weaving can occur.docs/phase-5-eofrannas-warp.md

The quotation comes from the phase 5 document, where the warp is the onboarding that registers the device and sets up the accounts, keys and privacy rules before anything else runs. On this page I use the word for Éofránna’s context assembly and Chibuelassa’s retrieval, which are written but have no connection in the CSV yet, and the two dashed bands to the right of the matrix stand for them. Other parts of the system are unfinished too, and STUBS_AND_PLACEHOLDERS.md lists the production code that reports success before the real work is written, including these five:

  • Calendar eventEmits action:calendar:create and returns success, though nothing reaches Google Calendar yet.
  • Email draftEmits action:email:draft and returns success, though nothing reaches Gmail yet.
  • Daily summaryReturns the literal string Daily summary for ${date}, where it should ask the LLM to summarise the day’s activities.
  • Discover devicesAlways returns [], since mDNS discovery isn’t written yet.
  • Pair with codeCreates a fake device and stores it, without any real P2P handshake yet.

Two items on the same list are done: creating a task calls the Google Tasks API, and the Ollama connection test sends a request to localhost:11434.

A covenant from the source

This is the start of song.covenant.ts, the file that defines a notification, with a gap where I’ve left out the imports and a smaller schema. Its comment block names the realm the song belongs to, the components that send it and the ones that receive it in the myth’s vocabulary, and the Zod object under it is the covenant every notification is checked against.

/**
 * Lúronwy Song Covenants
 *
 * Covenants for songs in Lúronwy's realm. Songs are what Lúronwy creates
 * from whispers—notifications that carry across realms to reach the user.
 *
 * @module covenants/luronwy/song
 *
 * @terminology
 * - **Song**: A notification that Lúronwy composes from whispers and sends
 *   across realms. "Lúronwy gives voice to what Míharáe perceives. They take
 *   the whispers moving through the tapestry and shape them into something
 *   that can travel."
 * - **Channel**: The pathway through which songs travel (WhatsApp, desktop).
 * - **Verse**: The structure of a song (its rules and conditions).
 *
 * @realm luronwy
 * @known Processing handler, action handler
 * @knower Notification service, WhatsApp client, desktop notifier
 *
 * @see docs/specs/notification-system.md for technical specification
 */

// … lines 23–64 (imports and the song type covenant) left out

export const songCovenant = z.object({
  id: uuidCovenant,
  type: songTypeCovenant,
  priority: songPriorityCovenant,
  title: nonEmptyStringCovenant,
  body: nonEmptyStringCovenant,
  channels: z.array(songChannelCovenant).min(1),
  activityId: uuidCovenant.optional(),
  actionId: uuidCovenant.optional(),
  createdAt: dateCovenant,
  sentAt: dateCovenant.optional(),
  acknowledgedAt: dateCovenant.optional(),
  dismissedAt: dateCovenant.optional(),
  metadata: metadataCovenant,
});

packages/shared/src/covenants/luronwy/song.covenant.ts · lines 1–22 and 65–79

The myth’s names for the code’s terms

These tables are copied from packages/shared/src/covenants/README.md, where I set out the names the schema module uses, so that a Zod schema is exported as a covenant and validation is called seeking accord.

MythCodeMeaning
CovenantSchemaA sacred agreement defining the structure a lyric must take. From the ontology: "Eternal objects are pure potentials—the form a lyric might take before it takes it."
In AccordValidWhen data harmonises with its covenant. The known and knower are in agreement.
DiscordInvalidWhen data breaks from its covenant. The thread is broken.
Seek AccordValidateThe act of checking whether data is in accord with a covenant.
LoomRegistryWhere covenants are held, ready to be drawn for weaving.
LyricEventA unit of communication between known and knower.
KnownProducerThe entity transmitting a lyric.
KnowerConsumerThe entity receiving and perceiving a lyric.
RealmDomainA non-physical space (Míharáe’s realm, Lúronwy’s realm, the Tapestry).

The types of lyric

WhisperActivity eventA lyric from the orgán (computer) perceived by awareness. Míharáe perceives whispers.
SongNotificationA lyric that Lúronwy transforms from whispers and sends across realms.
ResonanceSync eventWhen songs echo across multiple devices, keeping the tapestry in harmony.
PulseHealth eventThe heartbeat of the tapestry itself.
ThreadConfig eventThe threads that bind and configure the weave.
PerceptionProcessingMíharáe’s act of perceiving and classifying whispers.
ActionActionActions that give weight to connections in the tapestry.

The process philosophy in the myth

The myth takes its ontology from process philosophy, from Whitehead’s actual occasions and Simondon’s individuation. In the README a sidhe, an orgán or a gathering is made of its relations and its history of lyrics given and received, and the paragraph ends on the two sentences below.

There is no entity beneath the process.
The process is the entity.

README.md, line 110

Occasion
The fundamental unit of the tapestry. Not a thing but a happening. Each lyric exchanged, each weight adjusted, each thread woven constitutes an occasion. Occasions perish as they occur, but their effects propagate through the tapestry.
Prehension
How an occasion grasps what came before. Every new lyric prehends prior lyrics, prior weights, prior patterns in the weave. The knower does not receive a message in isolation but feels the entire history that produced it.
Concrescence
The process by which an occasion comes into being. A lyric does not exist and then get transmitted. It concresces—assembles itself from the potentials available—and in that assembling, it becomes actual.
Metastability
A state rich with potential but not yet resolved. The tapestry is never in equilibrium. It holds tensions that will eventually discharge into new forms, new connections, new patterns of relation.

README.md, from “Events and Becoming” and “Individuation”

The forest breathes with the efforts of the weavers, its orgáin and Sidhe interwoven in a melody of change and renewal.

The quotations, code and data on this page come from the goronwy repository:

  • README.md · the myth, the ontology, the glossary
  • ARCHITECTURE.md · the nine-step Data Flow and privacy split
  • docs/component-connectivity-matrix.csv · the 66 connections in the matrix
  • docs/component-connectivity-matrix.md · the summary figures and four of the five flow names
  • packages/shared/src/covenants/README.md · the concordance
  • packages/shared/src/covenants/luronwy/song.covenant.ts · the specimen
  • docs/phase-5-eofrannas-warp.md · docs/STUBS_AND_PLACEHOLDERS.md · the warp quotation and the stubs