Skip to content

How Moʻolelo works ​

Moʻolelo is a federated enterprise knowledge platform. It has four jobs:

  1. Ingest records from your source systems and normalize them into a uniform shape.
  2. Index the normalized records — lexically (full-text), semantically (embeddings), and structurally (knowledge graph).
  3. Curate the corpus — detect superseded entries and apply the tenant's governance rules.
  4. Serve the corpus through three surfaces (search, graph, supersession) — every one of them honoring source-system permissions end-to-end.

This page walks the data path end to end.

The data path ​

text
your source                    ┌── webhook delivery ──┐
systems                        │                      │
(GitHub,                       ▼                      │
 Confluence,             webhook receiver             │
 Jira,                         │                      │
 SharePoint)                   ▼                      │
                         ┌─ ingestion topic ◀─── connector
                         │                            │
                         ▼                  (also: backfill via API)
                 normalize envelope
                         │
                         ├──▶ durable record store (Apache Iceberg)
                         │            │
                         │            └──▶ queryable directly:
                         │                  Trino, DuckDB, Spark, …
                         ▼
                 parse + chunk + embed
                 (Docling for documents,
                  tree-sitter for code,
                  bge-m3 for embeddings)
                         │
                         ├──▶ hybrid search index (Apache Vespa)
                         │            │
                         │            └──▶ queryable via search API / MCP
                         │
                         └──▶ knowledge graph (NebulaGraph)
                                      │
                                      └──▶ one-hop "see also" via graph
                                           expansion at query time

Every arrow is durable. If any stage fails, the platform retries from the last successful checkpoint without dropping records or duplicating writes.

Three surfaces, one knowledge substrate ​

Moʻolelo isn't a search index sitting on top of a normalizer. It's a knowledge substrate with three complementary surfaces, all sharing the same chunks, the same access controls, the same audit log, and the same residency boundary:

Apache Vespa hybrid retrieval — BM25 (lexical similarity) blended with cosine similarity over a 1024-dimensional dense embedding (BAAI/bge-m3 multilingual). You configure the blend per query (the alpha parameter). Per-tenant ACL filtering is enforced before results leave the coordinator, and superseded entries get a superseded_by marker (or are filtered / demoted, per the tenant's policy).

See Querying via Vespa.

Knowledge graph ​

NebulaGraph holds one vertex per entity (page, issue, PR, document) plus refers_to edges that the projector extracts from each chunk's text — Jira-style keys (PROJ-123), GitHub owner/repo#N (or bare #N in a GitHub chunk), Confluence inter-page markdown links, and URLs into *.atlassian.net/browse/, *.atlassian.net/wiki/spaces/.../pages/, and github.com/.../issues|pull/. The graph is populated in the same streaming pipeline as the chunks — graph projection is not a batch job.

When graph expansion is enabled for a tenant, every search hit can carry a "see also" set of one-hop neighbors. The coordinator filters both the hit and its neighbors through the same OpenFGA check, so a user who can't read a related entity never sees it.

Stub vertices give the graph forward references: if a Confluence page mentions PROJ-123 before the Jira connector is running, a stub jira||issue|PROJ-123 vertex is created with record_type = "unknown". When the real entity arrives, the stub is upgraded in place — same canonical entity id, last-write-wins on the vertex properties.

See Graph expansion.

Supersession ​

The platform watches the corpus for entries replaced by fresher, more authoritative ones — duplicate pages, an issue closed by a PR, an older policy doc replaced by the next quarter's version — and demotes the stale ones at retrieval time. The "what supersedes what" decision follows an operator-defined per-tenant authority hierarchy, so the algorithm follows your governance rules instead of guessing.

See Supersession.

The two storage layers ​

Records live in two places, and the distinction matters:

The durable record store ​

Every record your sources produce ends up in an Apache Iceberg table managed by Project Nessie. Iceberg is the source of truth: if anything else needs rebuilding (the search index, the knowledge graph, a downstream analytics warehouse, a backup), it gets rebuilt from this store.

You can query the Iceberg tables directly with any Iceberg-aware tool — Trino, Spark, DuckDB, PyIceberg, Snowflake's external-table support, or anything else that speaks the Iceberg REST catalog protocol. See Querying via Iceberg.

The Iceberg tables live on object storage that you own — S3, MinIO, Google Cloud Storage, or Azure ADLS Gen2. Moʻolelo holds the catalog and the Parquet files; you hold the bucket.

The serving layer ​

For interactive use, records are projected into two complementary indexes:

  • Apache Vespa stores chunks with their text, embedding, source provenance, structural metadata (heading path, file path, line range), and the access-control attributes the OpenFGA Searcher plugin needs.
  • NebulaGraph stores entity and chunk vertices plus the typed edges between them (child_of for chunk→parent, refers_to for cross-document references, supersedes for replacement decisions).

Both indexes are projections of the Iceberg ground truth. Per ADR-013, ground truth and derived knowledge live in separate Iceberg tables — anything the supersession engine or future reference extractors infer lands in derived_* tables, never in the same table as the ingest record.

Connectors ​

A connector is the bridge between Moʻolelo and one source system. Four are supported today:

  • GitHub — repositories' issues and pull requests.
  • Confluence Cloud — pages and blog posts in selected spaces. Storage-format markup is converted to clean Markdown by the connector before publishing; see Connecting Confluence.
  • Jira — issues in selected projects.
  • SharePoint — drive items in selected sites (via Microsoft Graph).

Each connector runs in two modes:

  • Backfill when you first onboard a source. The connector walks the source's REST API and publishes every existing record.
  • Webhook for steady state. The source pushes change notifications to Moʻolelo, which converts them into records.

Connectors are configured per tenant in a Postgres table. Adding a source you weren't using before is an SQL INSERT; nothing else to redeploy.

See Connecting sources for per-source setup.

Tenant model ​

Moʻolelo is multi-tenant. Each tenant has:

  • Its own connector configurations (which sources, which auth, which spaces / repos / sites).
  • Its own license entitlement (employee count, events per day, region count).
  • Its own supersession authority matrix and retrieval policy.
  • Its own audit log entries.

Single-tenant deployments use a well-known sentinel tenant id of default.

Region model ​

Moʻolelo is region-aware. A region is a deployment of the data plane (Pulsar + Iceberg + Vespa + NebulaGraph + the Moʻolelo services) that holds data subject to a particular jurisdiction. A multinational deployment runs one region per legal jurisdiction — typically eu-central, us-east, apac-east, etc.

Personal data — names, email addresses, anything that identifies a specific person — is stored exclusively in the home region of that person's data subject. The platform routes tokenization and detokenization requests to the right regional vault. Cross-region queries federate without copying personal data across regions.

Single-region deployments are the simplest shape and require no special configuration; the residency model is what you opt into when you need to go multi-region.

See Data residency.

Where to next ​

  • Data residency — how Moʻolelo handles personally-identifiable data across jurisdictions.
  • Security model — authority chains, audit, and the license key.
  • Access control — OpenFGA, authority chains, and the in-Vespa filter.
  • Supersession — how the platform identifies stale duplicates and keeps results clean.
  • Graph expansion — related-entity hits via the cross-document reference graph.
  • Connecting sources — set up your first connector.

Moʻolelo — self-hosted federated enterprise knowledge platform.