Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Graviola Glossary

Navigation: This glossary deepens vocabulary used across the book. For the product overview first, see What Graviola is and Capabilities today. For future direction, see Architectural trajectory. For unresolved design questions that span multiple terms, see Outlook and open questions.

A working vocabulary for the Graviola framework: federated, schema-evolving, local-first semantic data infrastructure. This glossary names the concepts Graviola relies on, points at the literature and prior projects that defined or refined each one, and gives short examples grounded in Graviola's actual use cases (cultural heritage, personal information management, offline-first field deployments).

The glossary is organized in layers, working roughly from foundations outward. Cross-references between entries use bold on first mention. Each entry has a short definition, an Example where one helps, See also cross-references, and References with links to literature or prior projects.

A note on optionality. Graviola is built from small, composable libraries. Most of the machinery described here — lenses, IVM, signed states, reasoning — is optional. Many Graviola applications use a single fixed schema with classical migrations (see Classical Migration) and never touch the lens engine; others use only the UI dispatch layer over a Prisma-backed PostgreSQL or MongoDB store. The architecture is designed so that none of these advanced concepts becomes a blocker for the simple cases.


1. Foundations

1.1 Schema-as-Data

Schemas (LinkML, JSON Schema, SHACL shapes) are not ambient configuration baked into deploys but first-class documents with @ids that travel through the same sync layer as the data they describe. A consequence: schemas can be authored, versioned, signed, and migrated by the same machinery as any other entity.

Example: On a ship with intermittent connectivity, a domain expert authors a JSON Schema via JSON Forms. The schema syncs across peers via Yjs/WebRTC alongside the data conforming to it.

See also: Lens-as-Data, Federated Sync Layer, Entity Version.

References:


1.2 Structural Dispatch

The architectural principle that behavior — UI rendering, mapping, validation, calculation, lens application — is bound to the shape declared by a schema (or to a property carried by an entity), not to a nominal type or class. This single pattern recurs at every layer of Graviola and is what allows components to survive Schema Drift without code changes.

Dispatch is itself a schema-level operation: testers match against Scopes (schema-node pointers) rather than Binding Paths (data traversals). This is why a renderer registered for #/properties/birthDate works against any Person instance without further configuration.

Example: JSON Forms resolves a renderer for {type: "string", format: "date"} regardless of which entity type contains the field. The same principle drives lens dispatch by Entity Version and class derivation by property (see Derived Versioned Class).

See also: Scope, JSON Forms, Declarative Mapping.

References:


1.3 Federated Sync Layer

The transport-and-replication substrate (in Graviola: Yjs, optionally over WebRTC, WebSocket, or Solid Pods) that moves both data and schema documents between peers without assuming a central authority. The sync layer makes no semantic decisions; it only guarantees eventual consistency of opaque documents.

Example: Ship deployment where servers are pure relays and have no plaintext access; peers sync end-to-end-encrypted documents and resolve schema versions locally on reconnection.

References:

  • Yjs
  • Local-first software (Kleppmann, Wiggins, van Hardenberg, McGranaghan, Ink & Switch, 2019)
  • Shapiro, Preguiça, Baquero, Zawirski, "Conflict-Free Replicated Data Types" (2011)

1.4 Reasoning-Compatible, Reasoner-Optional

Graviola's conceptual model is shaped by description-logic and rule-based reasoning (property-driven class derivation, entailment, transitive sameAs), but Graviola does not ship a reasoner. Where the underlying datastore supports reasoning (e.g., a triple store with OWL RL or a SHACL-AF engine), derivations can be materialized; where it does not, the same derivations can be computed at extraction time by Graviola's pipeline. Both paths produce the same query semantics for the cases Graviola cares about.

See also: Derived Versioned Class.

References:


1.5 Scope

A pointer into a schema document — a JSON Pointer such as #/properties/name — that identifies a schema node: a property definition, a type definition, or a rule. Scopes exist at schema-compile time and are absolute relative to a single schema document; they answer the question where in the schema does this apply? JSON Forms uses scopes to bind UI elements to schema nodes (scope: "#/properties/name" means "this UI element corresponds to this schema node"). A scope navigates the schema document, not the data graph; it never crosses a $ref to another entity and has no concept of a current instance.

In knowledge-representation terms a scope is a TBox pointer: it addresses the schema, not the data.

Example: A renderer registry tester matching scope: "#/properties/birthDate" selects the schema property declaration regardless of which Person instance is rendered. The same scope is correct on the empty form, on a half-filled form, and on a saved entity.

See also: Binding Path, Structural Dispatch, JSON Forms.

References:


1.6 Binding Path

A traversal through instance data, guided by the schema, that resolves to one or more data values relative to a current entity. A binding path such as patch.lane.owner starts at "the current instance," follows declared relations across $ref boundaries, and may fan out to many values when any hop is an array. Paths exist at runtime, against a live store; they answer the question what value do I need from the data graph?

In knowledge-representation terms a binding path is an ABox traversal, shaped by the TBox: the schema declares which hops are valid; the data supplies the values.

Example: A formula binding EQ(ownerId, currentUserId) resolves ownerId by following lane.owner.id from the current Patch. Substituting a Scope here would be a category error: schema nodes have no runtime values to compare.

Rule of thumb: use a Scope when you are describing something about the schema structure itself — which property a rule applies to, which field a renderer corresponds to, which definition an annotation targets. Use a binding path when you are describing a traversal through data — what value to retrieve, what relation to follow, what to compute over. Scopes are answered by the schema alone; binding paths are answered by the schema plus the data.

See also: Scope, Calculated Field, Structural Dispatch.


2. Schema Evolution & Versioning

2.1 Schema Version

A specific, content-addressable state of a schema document, identified by an @id and typically a semver tag. Schema versions are themselves documents and live in the same sync layer as data (see Schema-as-Data).

See also: Entity Version, Lens.


2.2 Entity Version

A property — gra:version or equivalent — carried by each named entity, recording which Schema Version the entity was authored under. Version is a property of the entity, not (only) of its container or store. This is what makes mixed-version data within a single store the normal case rather than an exception: a query for entities of a given conceptual type returns instances of all versions, and refinements by version are just property filters.

Example: A query against a federated person index returns {@id: ..., @type: ex:Person, gra:version: "0.3.2", name: ...} and {@id: ..., @type: ex:Person, gra:version: "0.4.5", forename: ..., surname: ...} side by side. The consumer's tool decides whether to apply a Lens based on the gra:version it sees.

See also: Derived Versioned Class, Schema Drift.


2.3 Derived Versioned Class

A conceptual subclass of an entity type, derived at runtime by the value of a property — most importantly Entity Version, but the pattern is general. ex:Person_V2_3_0 is the (conceptual) subclass of ex:Person whose members carry gra:version "2.3.0". Such derived classes can drive query refinement, dispatch in the graph-to-JSON extraction pipeline, and lens selection.

This is the same pattern as deriving ex:Author from ex:Person by the presence of an authored work, or ex:SignedDocument from ex:Document by the presence of a Signed State — property-driven subclass derivation, well-understood in description logics. Graviola applies it to versioning.

Example: The graph-to-JSON pipeline for a visualization plugin declared at V0_3_8 selects entities that are either ex:Person_V0_3_8 directly or are reachable via lens composition from another version. The selection is expressed as a query over gra:version, not as a separate negotiation step.

See also: Structural Dispatch, Reasoning-Compatible, Reasoner-Optional.

References:

  • Baader, Calvanese, McGuinness, Nardi, Patel-Schneider, The Description Logic Handbook (Cambridge University Press, 2003) — for the general theory of property-driven class derivation.

2.4 Schema Drift

The condition in which entities within a federation — or within a single store — carry different values of Entity Version for the same conceptual type. Drift is the normal case in Graviola, not an error to recover from. Tools handle drift either by applying a Lens chain, by restricting their query to a specific Derived Versioned Class, or by falling back to Classical Migration where the application owns the model.

References:

  • COPE / Edapt (Herrmannsdoerfer et al.)
  • Curino, Moon, Zaniolo, "Graceful database schema evolution: the PRISM workbench" (VLDB 2008).

2.5 Lens

A pair of transformations between two schema versions (or between two parallel schemas) consisting of a forward function (get) and a reverse function (put). Lenses are Graviola's primary mechanism for handling Schema Drift. The lens engine is an optional, pluggable component — a concrete AbstractDatastore implementation may or may not enable it, and many Graviola applications run without it.

Example: A lens from Person_V1 (single name field) to Person_V2 (forename, surname) defines how to split forward and how to recombine backward.

See also: Asymmetric Lens, Symmetric Lens, Lens Law, Lens Composition.

References:


2.6 Asymmetric Lens

A lens where one side is canonical and the other is a view. The reverse direction reconstructs the source from the view plus the original source. Most version-pair migrations are asymmetric.


2.7 Symmetric Lens

A lens where neither side is a strict view of the other; both sides may hold information the other lacks. Necessary for cross-vocabulary alignment (e.g., Graviola's local model ↔ Wikidata) where each side has fields the other doesn't.

References:


2.8 Lens Law

A property a well-behaved lens must satisfy. The three canonical laws:

  • GetPut: getting a view and putting it back unchanged yields the original source.
  • PutGet: putting a view, then getting, yields what was put.
  • PutPut: putting twice equals putting once with the latest value (very well-behaved lenses only).

Lenses that fail PutGet are Lossy and require Witness Preservation to round-trip safely.


2.9 Lens-as-Data

Lenses are themselves serializable JSON-LD documents with @ids, syncing through the same Federated Sync Layer as schemas and data. A lens can be authored, versioned, and signed independently of code.

Example: A historian signs a lens migrating heritage Person_V1 → Person_V2, vouching that the split of name into forename/surname was performed correctly for their corpus. The signature itself is a Signed State over the lens document.

References:


2.10 Lens Composition

The act of chaining lenses (A→B, B→C, C→D) into a single lens (A→D). Composition is associative; well-behavedness composes. In Graviola, a peer encountering data at V0_3_2 while running V0_4_5 assembles the migration chain by composition.

See also: Lens Fusion.


2.11 Lens Fusion

Static algebraic simplification of a composed lens chain before execution: a rename followed by a rename of the same field collapses; an add followed by a remove cancels. Graviola's "compile to fast runtime struct" step is fusion, not codegen.

References:


2.12 Lens Operator Catalog

The fixed, small set of lens primitives from which all migrations are built. Cambria's catalog: rename, hoist, plunge, wrap, head, add, remove. Graviola's catalog will likely overlap heavily; the design question is granularity (more primitives = more fusion opportunities; fewer = simpler authoring).


2.13 Lossy Lens

A lens whose forward direction discards information that the reverse direction cannot recover from the view alone. Splitting name → (forename, surname) is lossy in reverse if the original whitespace, ordering, or particle handling matters.

See also: Witness Preservation.


2.14 Witness Preservation

The technique of carrying a small companion record alongside migrated data that records what would otherwise be lost. The reverse lens consults the witness when reconstructing the source.

Example: Forward migration of "van der Berg, Jan" to {forename: "Jan", surname: "van der Berg"} emits a witness {originalName: "van der Berg, Jan", splitStrategy: "comma-first"}.


3. Mapping & Integration

3.1 Declarative Mapping

A JSON-LD-flavored DSL (Graviola's existing implementation) describing how to transform a source document into a target document via path-based source/target pairs and optional named Mapping Strategies. Used today primarily for ingesting authority data (GND, Wikidata, DBpedia) into the local model.

Example: The wikidataPersonMapping in Graviola's existing codebase: source $.claims.P569[*].mainsnak.datavalue.value.time → target birthDate via the dateStringToSpecialInt strategy.

See also: Mapping Strategy, R2RML / RML.


3.2 Mapping Strategy

A named, reusable transformation function (concatenate, takeFirst, createEntity, dateStringToSpecialInt, etc.) referenced by id from a Declarative Mapping entry. Strategies receive the source value, the current target value, options, and a Strategy Context.


3.3 Strategy Context

The runtime environment passed to a mapping strategy: logger, IRI minter, authority access, secondary-IRI resolver, mapping table, and a createDeeperContext continuation for recursive mapping into nested entities.


3.4 Migration Lens vs. Cross-Source Query vs. Tool Projection

Three distinct mapping shapes that Graviola deliberately keeps separate:

  • Migration Lens: between two versions of the same conceptual schema; bidirectional in principle; used for Schema Drift.
  • Cross-Source Query: assembles a target document from one or more foreign sources (Wikidata, GND); typically forward-only; the existing Graviola Declarative Mapping is this.
  • Tool Projection: narrows a canonical entity to the fields a specific tool needs (e.g., a filelight visualization needs only {path, size, parent}); read-only; cheap.

Conflating these is a known failure mode of "universal data integration" projects.


3.5 Mediated Schema (LAV / GAV / GLAV)

The classical data-integration framings:

  • GAV (Global-as-View): the global schema is defined as views over local sources. Adding a new source requires updating the global schema.
  • LAV (Local-as-View): each local source is described as a view over the global schema. New sources join without touching the mediator. Best fit for Graviola.
  • GLAV: a hybrid.

References:


3.6 R2RML / RML

W3C-standard declarative mapping languages from relational (R2RML) or heterogeneous (RML) sources to RDF. Graviola's declarative mapping is a JSON-LD cousin of these, optimized for JSON Linked Data rather than serialization-level transformation.

References:


3.7 Ontology Alignment

The (largely separate) problem of relating concepts across vocabularies, e.g., declaring that schema:Person and foaf:Person refer to the same class. Often expressed via owl:sameAs, skos:exactMatch, skos:closeMatch. Distinct from Lens-based migration: alignment is about identity of concepts, lenses are about transformation of representations.

References:

  • Euzenat & Shvaiko, Ontology Matching (Springer, 2nd ed. 2013).

4. Calculated Fields & Reactivity

4.1 Calculated Field

A schema property whose value is derived from other fields by a declarative formula (HyperFormula-style or similar) rather than stored directly. Structurally equivalent to a one-directional lens (get only).

Formula inputs are addressed by Binding Paths, not by Scopes: a calc must read live values from the current entity (and its declared relations), so its references are ABox traversals shaped by the schema. Schema-node pointers would be a category error here — there is nothing to compute over until a path is resolved against actual data.

Example: Person.fullName calculated as CONCAT(forename, " ", surname); an aggregate calc on a Patch reads lane.owner.id via a binding path that crosses a $ref boundary.

See also: Binding Path, Stratification, Incremental View Maintenance.

References:

  • HyperFormula — the formula engine Graviola's calc layer is patterned after.

4.2 Dependency Graph

The DAG of which calculated fields read which other fields. Used to determine recomputation order and to detect cycles.


4.3 Stratification

The ordering of a Dependency Graph into layers such that each layer depends only on previous layers. Required for safe evaluation of recursive or aggregate calculations in Datalog-style systems.

References:


4.4 Incremental View Maintenance (IVM)

The technique of updating a derived view in response to input changes by computing only the delta, rather than re-evaluating from scratch. The performance backbone of any nontrivial Calculated Field system at scale.

References:

  • Gupta & Mumick, "Maintenance of Materialized Views: Problems, Techniques, and Applications" (IEEE Data Eng. Bulletin, 1995).
  • Differential Dataflow (McSherry et al.).

4.5 Differential Dataflow

The modern, industrial-grade form of IVM: a dataflow framework that maintains the result of arbitrarily complex relational and iterative computations under input changes, with provable efficiency. Likely overkill for in-browser Graviola but the right reference point for server-side calc-heavy workloads.

References:


4.6 Complexity Annotation

A declarative tag on a Calculated Field describing its computational cost class (e.g., O(1), O(n), O(n²)) and optionally its memory footprint. Used by the runtime to choose between eager and lazy evaluation strategies and to decide whether the calc is admissible in a given Capability Context.


4.7 Capability Context

The set of resources available to the current Graviola host: memory, persistence, network, server-presence, GPU, etc. Calculated fields and visualizations declare what they need; the runtime matches and either runs, degrades, or refuses.

Example: A calc that needs {memory: "high", server: true} is skipped on the encrypted-ship deployment and surfaced as "unavailable in this environment."


4.8 Calc-as-Pure-Derivation vs. Calc-as-Cached-Materialized-View

The unresolved design tension for federated calculated fields:

  • Pure derivation: each peer recomputes locally from synced inputs. Clean, always consistent, potentially expensive.
  • Cached materialized view: results are computed once (e.g., server-side) and synced; must invalidate correctly across version skew.

Genuinely an open problem when combined with Schema Drift across CRDT-synced peers. See Cross-version calc sync.


5. Authority, Trust, & Provenance

5.1 Authority

An external data source treated as a reference for entity identity and attributes (Wikidata, GND, DBpedia, VIAF). Graviola's Declarative Mapping layer was built primarily to ingest from authorities into the local model.


A link from a local entity to its corresponding entry in an Authority, typically expressed as owl:sameAs or via a domain-specific property. Enables later re-fetching, cross-referencing, and trust evaluation.

Example: A local Person with sameAs http://www.wikidata.org/entity/Q42 for Douglas Adams.


5.3 Primary IRI / Secondary IRI

Graviola's distinction between the local canonical IRI of an entity (primary) and any external Authority IRI it is linked to (secondary). The getPrimaryIRIBySecondaryIRI resolver in the Strategy Context mediates this.


5.4 Signed State

A cryptographically signed snapshot of an entity (or a subset of its fields, or a Lens document) attesting that a named party (historian, expert, institution) vouches for its correctness at a moment in time. Multiple signatures on the same data raise its Authoritative Value.

See also: Lens-as-Data.

References:


5.5 Authoritative Value

A computed score for a piece of data based on the number, identity, and reputation of its Signed States (and possibly the trust graph among signers). Used in open historical databases to surface plausible vs. contested entries. Concrete formula is application-defined.


6. Architecture & Deployment

6.1 Local-First

The architectural stance, articulated by Ink & Switch, that user data lives primarily on user devices and remains available, editable, and useful without a central server. Graviola is local-first by default; servers, when present, are transports or accelerators, not authorities.

References:


6.2 Browser/Server Symmetry

The Graviola constraint that core layers (lens engine, validator, IVM) run identically in browser and server environments. Drives the choice of pure JS / WASM implementations and forbids server-only dependencies in core packages.


6.3 Classical Migration

The traditional path of evolving a schema by writing imperative migration scripts run in staging and production, typically against a relational or document database via an ORM. Graviola supports this path explicitly: where an application has strong authorship over its data model and runs a centralized backend (e.g., Prisma on PostgreSQL or MongoDB), the Lens machinery is unnecessary and the application uses Prisma migrations directly. The lens engine is plugged into a concrete AbstractDatastore implementation only when Schema Drift across uncoordinated peers is actually a concern.

This dual path is deliberate. Lenses solve a real but specific problem (federated, uncoordinated, version-skewed peers); classical migration solves the common case (one team owns the database). Graviola treats both as first-class.


6.4 Spine vs. Tissue Packages

A monorepo discipline distinguishing spine packages (interfaces, contracts, types — versioned slowly, broadly depended on) from tissue packages (implementations — versioned freely, narrowly depended on). Reduces the sync burden of a 100-package monorepo.

Example: @graviola/mapping-contracts (spine) defines the DeclarativeMapping types; @graviola/mapping-strategies-cultural-heritage (tissue) implements specific strategies for that domain.


6.5 JSON Forms

The schema-driven form rendering library Graviola uses for UI generation. Embodies Structural Dispatch: a renderer registry resolves shape→component at runtime, decoupling UI from concrete entity types.

UI schema elements bind to schema nodes via a Scope (e.g., scope: "#/properties/name"). Scopes here address the schema, not the data — a property a Graviola application reuses when it adds annotations or rules at the same surface. Operations that read or write entity values (calculated fields, formula bindings, traversals across $ref) use Binding Paths instead.

See also: Scope, Binding Path.

References:


6.6 AbstractDatastore

Graviola's interface contract for a concrete data backend. Implementations include in-memory stores, Yjs-backed stores, SPARQL endpoints, Prisma-backed relational stores, and others. The lens engine, IVM layer, and signing layer are opt-in features that a given AbstractDatastore implementation may or may not expose; consumers of an AbstractDatastore discover available capabilities through its declared interface.

See also: Capability Context, Classical Migration.


Appendix: Reading Order for Newcomers

For a developer new to Graviola who wants to understand the conceptual stack, roughly in this order:

  1. Local-first software (Kleppmann et al., 2019) — the why.
  2. Project Cambria — the closest existing system.
  3. Foster et al., Combinators for Bidirectional Tree Transformations — the lens foundations.
  4. Lenzerini, Data Integration: A Theoretical Perspective — the federation framing.
  5. Existing Graviola Declarative Mapping code and example mappings (Wikidata person, GND).
  6. JSON Forms documentation — for the UI dispatch pattern that mirrors the data layer.