Try holonic in your browser -- 13 example notebooks running on JupyterLite. No install required.
A lightweight Python client for building holonic knowledge graphs (based on Cagel's four-graph holonic RDF model) backed by rdflib, Apache Jena Fuseki, or any SPARQL-compliant quad store.
Every Holon has four (or more!) named graphs, each answering a distinct question:
| Layer | Question | RDF Mechanism |
|---|---|---|
| Interior | What is true inside? | Named graph, A-Box triples |
| Boundary | What is allowed? | SHACL shapes, portal definitions |
| Projection | What do outsiders see? | External bindings, translated vocab |
| Context | Where does this belong? | Membership, temporal annotations |
The holon's IRI threads through all four layers as both the identity anchor and a subject in cross-layer triples.
The dataset IS the holarchy. Python methods are convenience, not architecture.
A holon is not a Python object containing four rdflib.Graph attributes. A holon is an IRI whose associated named graphs exist in an RDF dataset. Portals are RDF triples in boundary graphs, discoverable via SPARQL. Traversal runs CONSTRUCT queries against the dataset with GRAPH scoping. All state lives in the quad store.
pip install holonicOptional extras: holonic[dev], holonic[docs], holonic[fuseki], holonic[notebooks], holonic[viz].
conda-forgesupport is in progress. Until the feedstock lands, install viapipinside a conda or mamba environment.
Requires pixi.
pixi run -e dev first # editable install + lint + tests + docs
pixi run -e dev test # tests only
pixi run serve # jupyterlab with the example notebooksSee CONTRIBUTING.md for the full development setup, including the separate spec pixi environment used by the SPEC validation pipeline.
from holonic import HolonicDataset
ds = HolonicDataset() # rdflib in-memory backend
# Create a holon with multiple interior graphs
ds.add_holon("urn:holon:acme", "Acme Corp")
ds.add_interior("urn:holon:acme", '''
@prefix schema: <https://schema.org/> .
<urn:person:alice> a schema:Person ;
schema:name "Alice Chen" ;
schema:jobTitle "Engineering Lead" .
''', graph_iri="urn:holon:acme/interior/people")
ds.add_interior("urn:holon:acme", '''
@prefix schema: <https://schema.org/> .
<urn:person:alice> schema:workLocation "San Francisco" .
''', graph_iri="urn:holon:acme/interior/locations")
# Query across all interiors
rows = ds.query('''
PREFIX schema: <https://schema.org/>
SELECT ?person ?name ?location WHERE {
GRAPH ?g1 { ?person schema:name ?name }
GRAPH ?g2 { ?person schema:workLocation ?location }
}
''')| Backend | Import | Infrastructure |
|---|---|---|
RdflibBackend |
from holonic import RdflibBackend |
None (in-memory) |
FusekiBackend |
from holonic.backends.fuseki_backend import FusekiBackend |
Fuseki server |
| Custom | Implement HolonicStore protocol |
Any quad store |
# Fuseki backend
from holonic.backends.fuseki_backend import FusekiBackend
ds = HolonicDataset(
backend=FusekiBackend("http://localhost:3030", dataset="holarchy")
)Migrating from 0.3.x or 0.4.x? The
GraphBackendalias andregistry_graphkwarg were removed in 0.5.0. Seedocs/MIGRATION.mdfor the full checklist.
A holon's interior is a set of named graphs, not a single graph:
ds.add_interior(holon, ttl_a, graph_iri="urn:holon:x/interior/contacts")
ds.add_interior(holon, ttl_b, graph_iri="urn:holon:x/interior/payroll")# Register (writes triples into boundary graph)
ds.add_portal("urn:portal:a-to-b", source, target, construct_query)
# Discover (SPARQL query, not Python iteration)
portals = ds.find_portals_from("urn:holon:source")
path = ds.find_path("urn:holon:a", "urn:holon:c") # multi-hop BFS# Low-level: execute a portal's CONSTRUCT
projected = ds.traverse_portal("urn:portal:a-to-b",
inject_into="urn:holon:b/interior")
# High-level: find portal → traverse → validate → record provenance
projected, membrane = ds.traverse(
"urn:holon:source", "urn:holon:target",
validate=True,
agent_iri="urn:agent:pipeline",
)result = ds.validate_membrane("urn:holon:target")
# Validates union of all cga:hasInterior graphs
# against union of all cga:hasBoundary graphsTwo modes: CONSTRUCT (stays in RDF, storable in the holarchy) and Pythonic (exits RDF into dicts/LPG for visualization).
from holonic import project_to_lpg, ProjectionPipeline, CONSTRUCT_STRIP_TYPES
# Full LPG projection — types, literals, blank nodes, lists all collapsed
lpg = project_to_lpg(graph,
collapse_types=True, # rdf:type → node.types list
collapse_literals=True, # literals → node.attributes dict
resolve_blanks=True, # blank nodes → nested dicts
resolve_lists=True, # rdf:first/rest → Python lists
)
lpg.to_dict() # JSON-serializable
# Composable pipeline (CONSTRUCT + Python transforms)
lpg = (
ProjectionPipeline("viz-prep")
.add_construct("strip_types", CONSTRUCT_STRIP_TYPES)
.add_transform("localize", localize_predicates)
.apply_to_lpg(source_graph)
)
# Project a holon (merge interiors → LPG, store result)
lpg = ds.project_holon("urn:holon:air", store_as="urn:holon:air/projection/viz")
# Project the holarchy topology (holons as nodes, portals as edges)
topo = ds.project_holarchy()The package includes a lightweight OWL 2 RL vocabulary (holonic/ontology/cga.ttl) and SHACL shapes (cga-shapes.ttl) defining the structural concepts: cga:Holon, cga:Portal with subclasses cga:TransformPortal / cga:IconPortal / cga:SealedPortal, cga:hasInterior, cga:hasBoundary, cga:constructQuery, and others. Per-subtype portal semantics (TransformPortal requires a constructQuery; IconPortal and SealedPortal must not carry one) are enforced by SHACL shapes. See docs/source/ontology.md for the full concept map.
| Example | Description |
|---|---|
notebooks/01_holon_basics.ipynb |
Holon creation, multi-interior, membrane validation |
notebooks/02_portal_traversal.ipynb |
Portal discovery, multi-hop paths, provenance |
notebooks/03_projections.ipynb |
Type/literal/blank-node collapse, pipelines, holarchy projection |
notebooks/04_cco_to_schemaorg.ipynb |
Cross-standard data translation (CCO → Schema.org) |
notebooks/05_governed_boundaries.ipynb |
Governed boundary contracts: alignment holons, stewardship, classification enforcement |
notebooks/06_holon_subtypes.ipynb |
AgentHolon, AggregateHolon subtypes, SHACL shapes, ClassificationLevel enum |
notebooks/07_graph_metadata.ipynb |
Graph-level metadata, eager/off modes, refresh policies |
notebooks/08_scope_resolution.ipynb |
BFS scope resolution, predicates, ordering modes |
notebooks/09_console_views.ipynb |
Console dataclasses, neighborhood graphs, graphology export |
notebooks/10_projection_plugins.ipynb |
Projection plugin system, pipeline registration, provenance |
notebooks/11_dispatch_patterns.ipynb |
Synchronous, event-queue, and asyncio dispatch patterns |
notebooks/12_holarchy_viz.ipynb |
Holarchy topology (data-structure view, no optional deps) |
notebooks/13_visualization.ipynb |
Interactive yFiles widgets for holons, holarchies, provenance (requires holonic[viz]) |
Notebooks 01-12 run with the base install. Notebook 13 requires the optional viz extra (pip install holonic[viz]) for the yFiles-based widgets.
Try in browser: The hosted documentation includes a JupyterLite build that runs notebooks 01-12 in your browser without any local installation. Notebook 13 requires a local Jupyter install because yFiles widgets depend on a Jupyter server extension that Pyodide can't provide.
Notebooks are committed with outputs stripped; execute them locally with pixi run serve or run the lint check (pixi run check-notebooks) to confirm your working copy stays clean before committing.
pip install holonic[docs]
cd docs && sphinx-build -b html . _build/htmlOr
pixi run build_html_docsand open the index.html
pip install holonic[dev]
pytestor
pixi run test┌─────────────────────────────────────────────────────────┐
│ HolonicDataset │
│ (thin Python wrapper — SPARQL queries) │
├─────────────────────────────────────────────────────────┤
│ HolonicStore Protocol │
│ graph_exists · get/put/post/delete_graph │
│ query · construct · ask · update │
│ │
│ AbstractHolonicStore (ABC) │
│ recommended base + optional native hooks │
├──────────────────┬──────────────────┬───────────────────┤
│ RdflibBackend │ FusekiBackend │ YourBackend │
│ (rdflib.Dataset)│ (HTTP/SPARQL) │ (protocol impl) │
└──────────────────┴──────────────────┴───────────────────┘
Backends inherit AbstractHolonicStore for the recommended path (abstract-method enforcement plus hook points for optional native methods). Duck-typed HolonicStore protocol implementations also work — the library dispatches to native methods via hasattr where present, falling back to generic Python implementations otherwise.
The roadmap is tracked as R9.* requirements in docs/SPEC.md and open questions as OQ1–OQ10. Each iteration below names its theme; implementation order within an iteration is fluid.
- 0.5.0 -- Breaking cleanup: removed
GraphBackendalias,registry_graphkwarg/property (R9.18). Addedholon_typekwarg,iter_holons/iter_portals_*generators withlimit/offsetpagination (R9.11).bulk_load()for batch holarchy construction.list_named_graphs()confirmed mandatory (R9.17). Notebook reorganization with sectioned landing page. - 0.4.3 -- Ontology enrichment: all 68 properties defined, holon subtype shapes (AgentHolon, AggregateHolon), ClassificationLevel enum (breaking:
dataClassificationis now an ObjectProperty), OQ10 upper-ontology alignment strategy. - 0.4.2 -- Structural lifecycle completion:
remove_holon,remove_portal, extensibleadd_portalsupporting all CGA portal subtypes plus downstream subclasses (R9.20, R9.21, R9.22). - 0.4.1 -- JupyterLite in-browser docs, dispatch-patterns notebook, DOM comparison framing, visualization notebook restored (R9.19).
- 0.4.0 --
HolonicStoreprotocol (renamed fromGraphBackend), ABC split, optional native-dispatch hook (R9.8 -- R9.10). - 0.3.x -- Typed graphs, scope resolution, graph-level metadata, projection plugin system (R9.1 -- R9.7).
- Aggregated membrane health in the registry (R9.13)
- Additional scope predicate classes:
HasPortalProducing,HasShapeFor,LabelMatches(R9.14) - Optional BFO/CCO and gist alignment modules if downstream consumers request them (OQ10)
- Federation semantics across multiple registries (OQ7)
- Async variant of
HolonicStoreif demand emerges from async consumers (R2.5) - Graph-level tick semantics (OQ8)
- DOM-style event propagation as coordination primitive (OQ9)
See docs/source/dom-comparison.md for the framing of how the current synchronous API already maps onto DOM concepts; the open question is whether explicit machinery is warranted.
- Kurt Cagel, "The Living Graph: Holons and the Four-Graph Model," The Ontologist, March 2026
- Arthur Koestler, The Ghost in the Machine, 1967
- W3C SHACL Specification
- W3C PROV-O Ontology
