API Reference
HolonicDataset
The primary entry point. Wraps a HolonicStore and exposes holon,
portal, traversal, projection, and discovery operations.
- class holonic.HolonicDataset(backend=None, *, registry_iri='urn:holarchy:registry', registry_graph=None, load_ontology=True, metadata_updates='eager')[source]
Bases:
objectA holonic system backed by an RDF quad store.
- Parameters:
backend (
HolonicStore|None) – A HolonicStore implementation. Defaults to RdflibBackend (in-memory rdflib.Dataset). Any duck-typed object satisfying the protocol works;AbstractHolonicStoreis the recommended base class for custom implementations.registry_iri (
str) – IRI of the named graph holding holon/portal declarations and graph-level metadata. Default:urn:holarchy:registry.registry_graphis accepted as a deprecated alias.load_ontology (
bool) – If True (default), load the CGA ontology and shapes into the dataset on construction.metadata_updates (
str) – One of"eager"(default) or"off". See § D-0.3.3-2.registry_graph (str | None)
- __init__(backend=None, *, registry_iri='urn:holarchy:registry', registry_graph=None, load_ontology=True, metadata_updates='eager')[source]
Construct a HolonicDataset.
- Parameters:
backend (
HolonicStore|None) – A HolonicStore instance. Defaults to RdflibBackend().registry_iri (
str) – IRI of the registry graph (holon/portal declarations and graph-level metadata). Default: urn:holarchy:registry. In 0.3.x this parameter wasregistry_graph; the old name is still accepted with a DeprecationWarning and will be removed in 0.5.0.registry_graph (
str|None) – Deprecated alias forregistry_iri. Do not use both.load_ontology (
bool) – Whether to auto-load the CGA ontology into the store.metadata_updates (
str) – One of"eager"or"off". When"eager"(default), graph-level metadata is refreshed on every library-mediated write to a layer graph. When"off", callers refresh explicitly viarefresh_metadata(). See docs/DECISIONS.md § D-0.3.3-2.
- property registry_graph: str
Deprecated alias for
registry_iri. Read-only.Kept for 0.3.x compatibility; access does NOT emit a warning (too noisy for existing code). The constructor parameter by the same name DOES warn. Scheduled for removal in 0.5.0.
- add_holon(iri, label, *, member_of=None)[source]
Declare a holon in the registry. Returns the holon IRI.
- add_interior(holon_iri, ttl, *, graph_iri=None)[source]
Parse TTL into a named graph and register it as a holon’s interior.
- add_boundary(holon_iri, ttl, *, graph_iri=None)[source]
Parse TTL into a named graph and register it as a holon’s boundary.
- add_projection(holon_iri, ttl, *, graph_iri=None)[source]
Parse TTL into a named graph and register it as a holon’s projection.
- add_context(holon_iri, ttl, *, graph_iri=None)[source]
Parse TTL into a named graph and register it as a holon’s context.
- remove_holon(iri)[source]
Remove a holon and all its associated state from the dataset.
Completes the CRUD lifecycle started by
add_holon(). Cleans up the holon’s registry entry, all layer graphs, graph-level metadata records, and any portals incident to the holon.- Parameters:
iri (
str) – The holon’s IRI.Returns
-------
bool –
Trueif the holon existed and was removed.Falseif the IRI was not found in the registry (idempotent — not an error).Notes
-----
removed (What is)
triple (- The holon's registry entry (cga:Holon type) –
rdfs:label,cga:memberOf)
- Return type:
:param :
rdfs:label,cga:memberOf) :param - Allcga:hasInterior/hasBoundary/hasProjection: /hasContextbindings in the registry :param - The layer graphs themselves (viabackend.delete_graph): :param - Graph-typing triples for the layer graphs (cga:HolonicGraph:cga:graphRole— added by 0.3.4 eager typing) :param :cga:graphRole— added by 0.3.4 eager typing) :param - Graph-level metadata records (cga:tripleCount:cga:lastModified,cga:ClassInstanceCountinventoryrecords — added by 0.3.3)
- :param
cga:lastModified,cga:ClassInstanceCountinventory records — added by 0.3.3)
- Parameters:
(cga:holonLastModified) (- The per-holon rollup)
this (- cga:memberOf triples where OTHER holons reference) – holon as parent (those children become root-level; they are NOT themselves deleted)
target (- Any portals where this holon is the source or) – (delegated to
remove_portal())preserved (What is)
parentless (- Child holons (they become) – the semantic that the containment relationship is dissolved, not the child)
matches (not deleted —) – the semantic that the containment relationship is dissolved, not the child)
is (- Provenance activities referencing this holon (provenance) – immutable history)
metadata_updates="eager" (When)
once (metadata refresh fires)
per-layer (after the full removal rather than)
avoid (to)
cleanup. (redundant work during cascading)
iri (str)
- Return type:
- add_portal(portal_iri, source_iri, target_iri, construct_query=None, *, portal_type='cga:TransformPortal', extra_ttl=None, label=None, graph_iri=None)[source]
Register a portal in the source holon’s boundary graph.
The portal definition IS RDF in the boundary named graph. Discovery uses SPARQL, not Python lookups.
- Parameters:
portal_iri (
str) – IRI for the portal resource.source_iri (
str) – IRI of the source holon.target_iri (
str) – IRI of the target holon.construct_query (
str|None) – Optional SPARQL CONSTRUCT query that produces the target interior from the source. Omit for portal subtypes that do not carry a SPARQL transformation (e.g.cga:IconPortal,cga:SealedPortal, or downstream subclasses whose transformation is specified by a different predicate).portal_type (
str) – RDF type for the portal. Defaults to"cga:TransformPortal". Accepts a prefixed name ("cga:SealedPortal","ext:NeuralPortal") or a full IRI. The caller is responsible for ensuring the type resolves to a declared class.extra_ttl (
str|None) – Additional Turtle triples appended verbatim to the portal block before parsing. Useful for portal subclasses that carry extra predicates. Applied to both the boundary graph and the registry mirror. The string should NOT include@prefixdeclarations — the method prepends the standard prefix block.label (
str|None) – Human-readable label. Defaults to “<source> → <target>”.graph_iri (
str|None) – Explicit boundary graph IRI. Defaults to"<source_iri>/boundary".Returns
-------
str – The portal’s IRI (same as the input, returned for chaining).
Examples
--------
form (Minimal TransformPortal with CONSTRUCT (the 0.3.x/0.4.0)
- Return type:
:param : :param unchanged)::
ds.add_portal( "urn:portal:a-to-b", source_iri="urn:holon:a", target_iri="urn:holon:b", construct_query="CONSTRUCT { ?s ?p ?o } WHERE { GRAPH ?g { ?s ?p ?o } }", )
- Parameters:
query:: (SealedPortal with no CONSTRUCT) –
- ds.add_portal(
”urn:portal:sealed”, source_iri=”urn:holon:a”, target_iri=”urn:holon:b”, portal_type=”cga:SealedPortal”,
)
predicates:: (Downstream portal subclass carrying extra) –
- ds.add_portal(
”urn:portal:neural”, source_iri=”urn:holon:a”, target_iri=”urn:holon:b”, portal_type=”ext:NeuralPortal”, extra_ttl=’’’
@prefix ext: <urn:ext:> . <urn:portal:neural> ext:transformRef <urn:model:v1> ;
ext:portalWeight 0.87 .
’’’,
)
portal_iri (str)
source_iri (str)
target_iri (str)
construct_query (str | None)
portal_type (str)
extra_ttl (str | None)
label (str | None)
graph_iri (str | None)
- Return type:
- remove_portal(portal_iri)[source]
Remove a portal from the dataset.
Cleans up all triples with
portal_irias subject across every named graph that contains them (typically the source holon’s boundary graph and the registry mirror). The boundary graph itself is preserved; only the triples about this specific portal are deleted.- Parameters:
portal_iri (
str) – The portal’s IRI.Returns
-------
bool –
Trueif the portal existed and was removed.Falseif the IRI was not found in any graph (idempotent — not an error).Notes
-----
remove (Does NOT)
holons (- The source or target)
may (- The boundary graph itself (other portals or SHACL shapes) – live there)
portal (- Provenance activities referencing this)
metadata_updates="eager" (When)
affected (metadata for each)
removal. (graph is refreshed after the)
- Return type:
- find_portals_from(source_iri)[source]
Discover all portals originating from a holon. Pure SPARQL.
- Return type:
- Parameters:
source_iri (str)
- find_portals_to(target_iri)[source]
Discover all portals targeting a holon. Pure SPARQL.
- Return type:
- Parameters:
target_iri (str)
- find_portal(source_iri, target_iri)[source]
Find a direct portal between two holons. Returns None if none exists.
- Return type:
- Parameters:
- find_path(source_iri, target_iri)[source]
Find a portal chain via BFS over the SPARQL-discovered portal graph.
Returns a list of PortalInfo forming a path, or None if unreachable.
- Return type:
list[PortalInfo] |None- Parameters:
- traverse_portal(portal_iri, *, inject_into=None)[source]
Execute a portal’s CONSTRUCT query against the dataset.
The CONSTRUCT query is read FROM the dataset (not passed as arg). This is the graph-native pattern: the portal definition IS the traversal specification.
- traverse(source_iri, target_iri, *, inject=True, validate=True, agent_iri=None)[source]
High-level: find a portal, traverse it, optionally validate and record.
- Parameters:
source_iri (
str) – Source and target holon IRIs.target_iri (
str) – Source and target holon IRIs.inject (
bool) – If True, inject projected triples into the target’s first interior.validate (
bool) – If True, validate the target membrane after injection.agent_iri (
str|None) – If provided, record PROV-O provenance.Returns
-------
(projected_graph
membrane_result_or_none)
- Return type:
tuple[Graph,MembraneResult|None]
- validate_membrane(holon_iri)[source]
Validate a holon’s interior(s) against its boundary shape(s).
Collects all cga:hasInterior graphs as data and all cga:hasBoundary graphs as shapes, then runs pyshacl.
- Return type:
- Parameters:
holon_iri (str)
- record_traversal(portal_iri, source_iri, target_iri, agent_iri, *, context_graph=None)[source]
Record a portal traversal as a PROV-O Activity via SPARQL UPDATE.
- record_validation(holon_iri, health, agent_iri, *, context_graph=None)[source]
Record a membrane validation as a PROV-O Activity.
- Return type:
- Parameters:
holon_iri (str)
health (MembraneHealth)
agent_iri (str)
context_graph (str | None)
- collect_audit_trail()[source]
Collect the full provenance audit trail from context graphs.
Queries all PROV-O activities across every context graph in the dataset, correlates traversals with validations, and builds surface reports from boundary shapes.
- Return type:
Returns:
: AuditTrail
Complete structured audit of traversals, validations, derivation chains, and surface reports.
- materialize_rdfs(holon_iri, alignment_iris=None)[source]
Materialize RDFS entailment for a holon using alignment axioms.
Creates an /interior/inferred named graph containing the delta (new triples from RDFS closure not in the original interiors).
Returns the IRI of the inferred graph.
- project_holon(holon_iri, *, store_as=None, **lpg_kwargs)[source]
Project a holon’s interior(s) into an LPG-style structure.
Collects all cga:hasInterior graphs, merges them, and runs project_to_lpg(). Optionally stores the projection result as a named graph in the dataset.
- Parameters:
- project_holarchy(**lpg_kwargs)[source]
Project the entire holarchy structure into an LPG.
Nodes are holons; edges are cga:memberOf and portal connections. Useful for visualizing the holarchy topology.
Returns:
: ProjectedGraph
- apply_pipeline(holon_iri, pipeline, *, store_as=None)[source]
Apply a ProjectionPipeline to a holon’s merged interior(s).
- compute_depth(holon_iri=None)[source]
Compute nesting depth from the cga:memberOf chain.
Depth is not stored — it is derived from structure. A root holon (no memberOf) has depth 0. Each memberOf hop adds 1.
Uses a simple SPARQL query to fetch direct memberOf pairs from the registry graph, then walks the parent chain in Python. This avoids SPARQL property path limitations in named-graph contexts across different engines.
- list_holons_summary()[source]
Return lightweight holon summaries for browser/list views.
Single SPARQL query — no per-holon layer fan-out. Use
get_holon_detail()for the full picture of one holon.- Return type:
- get_holon_detail(holon_iri)[source]
Return the full holon descriptor including layer graph IRIs.
Returns None if the holon is not registered.
- Return type:
- Parameters:
holon_iri (str)
- holon_interior_classes(holon_iri)[source]
Return (rdf:type, instance count) pairs across a holon’s interior.
Empty list if the holon has no interior graphs or no typed instances. Counts are DISTINCT subject counts per class.
- Return type:
- Parameters:
holon_iri (str)
- holon_neighborhood(holon_iri, depth=1)[source]
Return a portal-bounded subgraph around a holon, depth-limited.
BFS over portals from the source holon; each hop adds the portal’s other endpoint to the node set and the portal itself to the edge set. Depth is the maximum number of portal hops from the source.
The result is shaped for direct serialization to graphology JSON via
NeighborhoodGraph.to_graphology(). Edge keys are deterministic (edge-NNNN) so re-fetches with the same backing data produce stable IDs for diffing.- Return type:
- Parameters:
- get_portal(portal_iri)[source]
Return the full portal descriptor including the CONSTRUCT body.
Returns None if no portal with that IRI is registered.
- Return type:
- Parameters:
portal_iri (str)
- portal_traversal_history(portal_iri, limit=50)[source]
Return recorded traversals attributable to a single portal.
See note in
sparql.pyPORTAL_TRAVERSAL_HISTORY_TEMPLATE — scoped by (source, target) pair, since the current provenance schema does not store the portal IRI as a structured triple. Returns an empty list if the portal is not registered.- Return type:
- Parameters:
- refresh_metadata(holon_iri)[source]
Recompute and persist metadata for all of a holon’s layer graphs.
Writes per-graph metadata (triple count, last-modified, class inventory) and the per-holon rollup to the registry graph. Use after out-of-band writes via
backend.put_graph()orbackend.update().Returns the refreshed per-graph metadata in the order returned by the registry’s
cga:hasLayerenumeration.- Return type:
- Parameters:
holon_iri (str)
- refresh_all_metadata()[source]
Refresh metadata for every holon in the registry.
Returns the number of holons refreshed. Use after bulk data loads that bypass the library’s mutation API.
- Return type:
- get_graph_metadata(graph_iri)[source]
Return currently-materialized metadata for a graph.
Returns
Noneif no metadata has been written. Userefresh_metadata()to materialize it.- Return type:
- Parameters:
graph_iri (str)
- resolve(predicate, from_holon, *, max_depth=3, order='network', limit=50)[source]
Walk the holarchy in BFS order and return predicate matches.
- Parameters:
predicate – A
ResolvePredicateinstance (HasClassInInterior,CustomSPARQL, or any object with the predicate protocol fromholonic.scope).from_holon (
str) – IRI of the starting holon.max_depth (
int) – BFS depth limit. Clamped to[0, 100].order (
str) –"network"(outbound+inbound portals, default),"reverse-network"(inbound only), or"containment"(cga:memberOfwalk).limit (
int) – Maximum number of matches. Clamped to[1, 10_000].Returns
-------
list[ResolveMatch] – Matches in BFS depth order. See
holonic.scopefor the dataclass and predicate types.
- register_pipeline(spec)[source]
Register a projection pipeline in the registry.
Validates that every step’s
transform_name(if any) is known to the plugin registry. RaisesTransformNotFoundErrorat registration time rather than later at run time.Returns the pipeline’s IRI.
- Return type:
- Parameters:
spec (ProjectionPipelineSpec)
- register_pipeline_ttl(ttl)[source]
Escape hatch: register a pipeline from caller-supplied Turtle.
Parses the Turtle into the registry graph without validation. Caller is responsible for conforming to the
cga:ProjectionPipelineSpec+cga:ProjectionPipelineStepvocabulary and for valid rdf:List ordering.
- attach_pipeline(holon_iri, spec_iri)[source]
Declare that a holon has access to a registered pipeline.
Writes
<holon_iri> cga:hasPipeline <spec_iri>into the registry graph. Idempotent at the RDF level (duplicate triples in the same graph are coalesced).
- list_pipelines(holon_iri)[source]
Return projection pipelines attached to a holon.
Each summary carries just iri, name, description, and step count — use
get_pipeline(iri)for full step content.- Return type:
- Parameters:
holon_iri (str)
- get_pipeline(spec_iri)[source]
Return the full pipeline spec as a
ProjectionPipelineSpec.Returns
Noneif no pipeline with the given IRI is registered. Steps are returned in their declared rdf:List order.- Return type:
- Parameters:
spec_iri (str)
- run_projection(holon_iri, spec_iri, *, store_as=None, agent_iri=None)[source]
Execute a registered pipeline against a holon’s interiors.
Merges the holon’s interior graphs, runs each step in declared order (transform first, then inline CONSTRUCT if present), and optionally stores the result as a named graph registered as a projection layer.
Records a
prov:Activityin the holon’s context graph with:prov:used <spec_iri>prov:generated <output_graph_iri>(ifstore_as)prov:startedAtTime/prov:endedAtTimeprov:wasAssociatedWith <agent_iri>(if provided)cga:transformVersionfor each transform usedcga:runHost,cga:runPlatform,cga:runPythonVersion,cga:runHolonicVersion
Raises
ValueErrorif the spec is not registered, orTransformNotFoundErrorif a step references an unknown transform.
Structural Lifecycle (0.4.2)
Complete CRUD surface for holons and portals. The add_* methods
from earlier releases are now paired with remove_* counterparts,
and add_portal() is extensible to all portal subtypes declared in
the CGA ontology plus downstream subclasses.
Holon lifecycle. HolonicDataset.add_holon(iri, label, ...)
creates a holon; HolonicDataset.remove_holon(iri) performs
cascading cleanup of the registry entry, all four layer graphs,
graph-typing triples, metadata records, per-holon rollup, and every
portal where the holon is source or target. Child holons that
reference the removed holon via cga:memberOf are orphaned but
preserved. Provenance activities are preserved because provenance
is immutable history. Idempotent — returns False for a
non-existent IRI.
Portal lifecycle. HolonicDataset.add_portal(iri, source_iri, target_iri, construct_query=None, *, portal_type="cga:TransformPortal", extra_ttl=None, ...) supports all portal subtypes. Pass
construct_query=None for referential or blocked subtypes; pass
portal_type to select the subclass; pass extra_ttl for
predicates carried by downstream subclasses.
HolonicDataset.remove_portal(portal_iri) deletes the portal’s
triples from every graph containing them while preserving the
boundary graph and sibling portals.
Portal subtype semantics. See ontology.md for
the per-subtype cga:constructQuery expectations enforced by SHACL
shapes: cga:TransformPortal requires one, cga:IconPortal and
cga:SealedPortal must not carry one.
Store Protocol (0.4.0)
- class holonic.HolonicStore(*args, **kwargs)[source]
Bases:
ProtocolMandatory interface for a quad-aware graph store.
Every backend must satisfy this protocol. The methods cover named-graph CRUD and SPARQL dispatch — enough for all holonic operations when combined with the library’s Python-side helpers (
MetadataRefresher,ScopeResolver,run_projection).Any object matching this protocol shape can be used with
HolonicDataset, regardless of whether it inheritsAbstractHolonicStore. Inheritance is recommended for the defaults-for-optional-methods it provides, but not required.Choosing between Protocol and ABC
Use the Protocol (
HolonicStore) for type annotations on library-public functions and APIs. It captures the structural contract without requiring inheritance from users:def do_something(store: HolonicStore) -> None: ...
Use the ABC (
AbstractHolonicStore) as the base class for new backend implementations. It adds@abstractmethodenforcement (so Python refuses to instantiate a subclass that forgets a method) plus hook points for optional-method defaults:class MyBackend(AbstractHolonicStore): def graph_exists(self, graph_iri): ... # ... all the other abstract methods
Examples:
The two first-party backends (
RdflibBackend,FusekiBackend) both inherit the ABC. Duck-typed protocol satisfaction works too, as verified byisinstance(backend, HolonicStore).See Also:
AbstractHolonicStore : Recommended base class for new backends. holonic.backends.rdflib_backend.RdflibBackend : First-party default. holonic.backends.fuseki_backend.FusekiBackend : First-party HTTP.
- parse_into(graph_iri, data, format='turtle')[source]
Parse serialized RDF into the named graph (append).
- query(sparql, **bindings)[source]
Execute a SELECT query. Return list of binding dicts.
Each dict maps variable names (without
?) to their values. Values are strings (IRIs/literals) — callers convert as needed.
- construct(sparql, **bindings)[source]
Execute a CONSTRUCT query. Return results as an rdflib.Graph.
- class holonic.AbstractHolonicStore[source]
Bases:
ABCAbstract base class for holonic stores with optional-method defaults.
Inheriting this is the recommended way to implement a backend. Subclasses define the mandatory methods (abstract here); the ABC provides Python fallback implementations of optional methods so backend authors don’t have to ship them.
Mandatory surface
Eleven methods marked
@abstractmethod: named-graph CRUD (graph_exists,get_graph,put_graph,post_graph,delete_graph,parse_into), SPARQL dispatch (query,construct,ask,update), and one utility (list_named_graphs). Python refuses to instantiate a subclass that doesn’t implement all eleven.Optional surface
Additional methods that backends MAY override to replace the library’s generic Python fallbacks with native, typically faster implementations. Discovery is duck-typed via
hasattr(store, method_name); no registration is required.As of 0.4.0, one optional method is recognized:
refresh_graph_metadata(graph_iri, registry_iri) -> GraphMetadata | Nonerecompute per-graph metadata (triple count, class inventory, last-modified timestamp) natively. The library’sMetadataRefresher.refresh_graphdispatches to this if the method exists on the store; otherwise it runs the generic Python implementation.
Future 0.4.x releases will add more optional methods for scope walking, bulk load, and pipeline execution (see SPEC R9.17).
Example:
A minimal backend implementing only the mandatory surface:
from holonic.backends.store import AbstractHolonicStore class MyBackend(AbstractHolonicStore): def __init__(self): self._store = {} # graph_iri -> set[(s, p, o)] def graph_exists(self, graph_iri): return bool(self._store.get(graph_iri)) def get_graph(self, graph_iri): from rdflib import Graph g = Graph() for triple in self._store.get(graph_iri, ()): g.add(triple) return g # ... other mandatory methods ...
A backend with a native metadata fast path:
class FusekiBackend(AbstractHolonicStore): # ... mandatory methods ... def refresh_graph_metadata(self, graph_iri, registry_iri): # Use Fuseki's native statistics endpoint stats = self._fetch_stats(graph_iri) return GraphMetadata( iri=graph_iri, triple_count=stats["count"], last_modified=stats["modified"], ... )
See Also:
- HolonicStoreThe Protocol view of the mandatory surface;
use this for type annotations on library APIs.
- holonic._metadata.MetadataRefresherDispatcher that
chooses native vs generic metadata paths.
- abstractmethod graph_exists(graph_iri)[source]
Return True if the named graph contains at least one triple.
Implementations SHOULD treat “does not exist” and “exists but empty” as equivalent — both return False. Callers use this as a cheap presence check before committing to a full read.
- abstractmethod get_graph(graph_iri)[source]
Return the named graph as an
rdflib.Graph.The returned graph is a copy for local processing; mutations do not flow back to the store. Callers wanting to mutate the backing state use
put_graph/post_graph/parse_into/update.If the named graph does not exist, implementations SHOULD return an empty
rdflib.Graphrather than raise.
- abstractmethod put_graph(graph_iri, g)[source]
Replace the named graph with the contents of
g.Existing triples in the named graph are removed; the new triples are then added. Atomic with respect to other callers where the backing store supports it; non-atomic implementations SHOULD document the window.
- abstractmethod post_graph(graph_iri, g)[source]
Append the triples in
gto the named graph.Existing triples are preserved. Duplicate triples are coalesced at the RDF level (a quad store stores each
(s, p, o, g)at most once).
- abstractmethod delete_graph(graph_iri)[source]
Delete the named graph entirely.
SHOULD be idempotent: deleting a non-existent graph is a no-op, not an error.
- abstractmethod parse_into(graph_iri, data, format='turtle')[source]
Parse serialized RDF and append into the named graph.
formatis an rdflib parser name; common values are"turtle","xml","n3","json-ld","nquads". Semantic equivalent topost_graph(graph_iri, rdflib.Graph().parse(data=data, format=format))but implementations MAY optimize (e.g. stream-parse into the backing store directly).
- abstractmethod query(sparql, **bindings)[source]
Execute a SPARQL SELECT query.
Returns a list of binding dictionaries, one per result row. Each dict maps variable names (without the leading
?) to their bound values. Values are Python scalars for literals (strings, ints, floats, booleans,datetimeobjects forxsd:dateTime) and strings for IRIs.bindingsis reserved for future parameterized-query support; implementations MAY raiseNotImplementedErroron non-empty bindings in 0.4.x.
- abstractmethod construct(sparql, **bindings)[source]
Execute a SPARQL CONSTRUCT query.
Returns the constructed triples as an
rdflib.Graph. The return value is a fresh graph, not bound to any named graph in the store; callers wanting to persist it useput_graphorpost_graph.bindings: seequery.
- abstractmethod ask(sparql, **bindings)[source]
Execute a SPARQL ASK query.
Returns True if the query has at least one solution, False otherwise.
bindings: seequery.
- abstractmethod update(sparql)[source]
Execute a SPARQL UPDATE (INSERT / DELETE / DROP / CREATE).
Mutates the backing store according to the update request. Callers using this path bypass the library’s metadata-refresh machinery; if
metadata_updates="eager"is the dataset policy, callHolonicDataset.refresh_metadataafter out-of-band updates to reconcile.
- abstractmethod list_named_graphs()[source]
Return the IRIs of all named graphs in the store.
Implementations SHOULD exclude graphs that exist as identifiers but contain no triples. The default graph (if the backing store has one) is NOT included; the library does not use the default graph and expects every triple to live in a named graph per R1.4.
In 0.3.x this was
GraphBackend. The old name is a deprecated alias through all of 0.4.x. Seedocs/MIGRATION.md.
Model Types
- class holonic.HolonInfo(iri, label=None, interior_graphs=<factory>, boundary_graphs=<factory>, projection_graphs=<factory>, context_graphs=<factory>)[source]
Bases:
objectDescriptor for a discovered holon.
- Parameters:
- class holonic.PortalInfo(iri, source_iri, target_iri, label=None, construct_query=None)[source]
Bases:
objectDescriptor for a discovered portal.
- Parameters:
- class holonic.MembraneResult(holon_iri, conforms, health, report_text, violations=<factory>, warnings=<factory>)[source]
Bases:
objectResult of SHACL membrane validation.
- Parameters:
- health: MembraneHealth
- class holonic.MembraneHealth(*values)[source]
Bases:
EnumClasses of health for a Holon Membrane.
- INTACT = 'intact'
- WEAKENED = 'weakened'
- COMPROMISED = 'compromised'
- class holonic.MembraneBreachError(result)[source]
Bases:
ExceptionRaised when a portal traversal would produce membrane-invalid data.
- Parameters:
result (MembraneResult)
- class holonic.SurfaceReport(holon_iri, target_classes=<factory>, required_fields=<factory>, optional_fields=<factory>, violations=0, warnings=0)[source]
Bases:
objectSummary of what a holon’s boundary requires (from SHACL shapes).
- Parameters:
- class holonic.AuditTrail(traversals=<factory>, validations=<factory>, derivation_chain=<factory>, surfaces=<factory>)[source]
Bases:
objectComplete provenance audit of all traversals and validations.
- Parameters:
traversals (list[TraversalRecord])
validations (list[ValidationRecord])
surfaces (dict[str, SurfaceReport])
- traversals: list[TraversalRecord]
- validations: list[ValidationRecord]
- surfaces: dict[str, SurfaceReport]
- class holonic.TraversalRecord(activity_iri, source_iri, target_iri, agent_iri=None, portal_label=None, timestamp=None)[source]
Bases:
objectA single portal traversal event from the provenance trail.
- Parameters:
Console Model (0.3.1+)
Lightweight dataclasses tuned for JSON serialization to web clients.
- class holonic.HolonSummary(iri, label=None, kind=None, classification=None, member_of=None, interior_triple_count=None, health=None)[source]
Bases:
objectLightweight holon descriptor for browser/list views.
Excludes layer graphs to keep the list query cheap. Use
HolonicDataset.get_holon_detail()for the full picture.- Parameters:
- class holonic.HolonDetail(iri, label=None, kind=None, classification=None, member_of=None, interior_graphs=<factory>, boundary_graphs=<factory>, projection_graphs=<factory>, context_graphs=<factory>, interior_triple_count=None, health=None, layer_metadata=<factory>, holon_last_modified=None)[source]
Bases:
objectFull holon descriptor including layer graph IRIs and registry triples.
- Parameters:
- layer_metadata: dict[str, GraphMetadata]
- class holonic.ClassInstanceCount(class_iri, count)[source]
Bases:
objectCount of instances of a single rdf:type within a holon’s interior.
- class holonic.NeighborhoodNode(key, label=None, kind=None, health=None, triples=0, size=10.0, node_type='holon')[source]
Bases:
objectStores metadata about a node in a neighborhood subgraph.
- Parameters:
- class holonic.NeighborhoodEdge(key, source, target, edge_type, label=None, health=None, size=1.0)[source]
Bases:
objectStores metadata about an edge in a neighborhood subgraph.
- Parameters:
- class holonic.NeighborhoodGraph(source_holon, depth, nodes=<factory>, edges=<factory>)[source]
Bases:
objectA neighborhood subgraph centered on a holon, depth-bounded.
Serializes to graphology’s native JSON via
to_graphology(). The console returns this directly to sigma.js.- Parameters:
source_holon (str)
depth (int)
nodes (list[NeighborhoodNode])
edges (list[NeighborhoodEdge])
- nodes: list[NeighborhoodNode]
- edges: list[NeighborhoodEdge]
- to_graphology()[source]
Return a graphology-compatible JSON payload.
Shape per https://graphology.github.io/serialization.html and the contract documented in
docs/GRAPH-COMPONENTS.mdof the holonic-console project.- Return type:
- class holonic.PortalSummary(iri, source_iri, target_iri, label=None, last_traversal=None, health=None)[source]
Bases:
objectLightweight portal descriptor for browser/list views.
- Parameters:
Graph-Level Metadata (0.3.3)
- class holonic.GraphMetadata(iri, triple_count=0, last_modified=None, refreshed_at=None, class_inventory=<factory>, graph_role=None)[source]
Bases:
objectPer-graph operational metadata, materialized in the registry.
Added in 0.3.3. Read via
HolonicDataset.get_graph_metadata(). Written on every library-mediated write to the graph; direct backend writes do not update it. CallHolonicDataset.refresh_metadata()after out-of-band writes.last_modifiedis UTC;refreshed_atis the time the current row was written (may be later thanlast_modifiedif a refresh ran without a content change).- Parameters:
- class_inventory: list[ClassInstanceCount]
See HolonicDataset.refresh_metadata(), refresh_all_metadata(),
and get_graph_metadata() for the read/write surface.
Scope Resolution (0.3.4)
- class holonic.ResolveMatch(iri, distance, evidence='')[source]
Bases:
objectA holon that satisfied the resolve predicate.
Attributes:
- iri :
The matching holon’s IRI.
- distance :
BFS hop count from
from_holon. 0 means the starting holon itself matched.- evidence :
Human-readable description of what matched (from the predicate’s
evidence()method).
- class holonic.HasClassInInterior(class_iri)[source]
Bases:
objectMatch holons whose interior graphs contain instances of
class_iri.Uses the 0.3.3 class inventory via the registry graph when the inventory is populated; falls back to a direct interior graph query otherwise. The fallback means
metadata_updates="off"deployments still get correct answers, just slower.- Parameters:
class_iri (
str) – The full IRI of the class to match against (e.g."urn:holonic:ontology:Holon").Examples
--------
a (Find any holon in the holarchy whose interior contains)
cga:TransformPortal:: –
- matches = ds.resolve(
HasClassInInterior(”urn:holonic:ontology:TransformPortal”), from_holon=”urn:holon:root”, max_depth=5,
)
- matches(backend, holon_iri, registry_iri)[source]
Return True if the holon’s interior contains an instance of
class_iri.Executes an ASK query against the backend. The query first consults the 0.3.3 class inventory in the registry and falls back to a direct interior scan if the inventory is not populated for this holon.
- Return type:
- Parameters:
backend (HolonicStore)
holon_iri (str)
registry_iri (str)
- class holonic.CustomSPARQL(ask_template)[source]
Bases:
objectMatch holons via a caller-supplied SPARQL ASK template.
The template must use the literal placeholder
{holon_iri}for the candidate holon IRI.{registry_iri}is also substituted if present. Substitution usesstr.replace, notstr.format, so normal SPARQL braces inGRAPH ?g { ... }do not need to be doubled.- Parameters:
ask_template (
str) – A SPARQL ASK query string with{holon_iri}(and optionally{registry_iri}) as literal substring placeholders.Examples
--------
data:: (Find holons with classified) –
- CustomSPARQL(‘’’
PREFIX cga: <urn:holonic:ontology:> ASK WHERE {
- GRAPH ?g {
<{holon_iri}> cga:dataClassification “CUI” .
}
}
’’’)
Notes
-----
find (CustomSPARQL is intended as an escape hatch. If you)
pattern (yourself using it repeatedly for the same)
consider
R9.14. (proposing a first-class predicate class via SPEC)
- matches(backend, holon_iri, registry_iri)[source]
Substitute placeholders and run the ASK query against the backend.
Uses
str.replacefor substitution, notstr.format, so SPARQL braces in the template body don’t need escaping.- Return type:
- Parameters:
backend (HolonicStore)
holon_iri (str)
registry_iri (str)
- class holonic.ScopeResolver(backend, registry_iri)[source]
Bases:
objectExecutes a scoped BFS walk against a backend.
Held by
HolonicDatasetand delegated to fromresolve(). Public construction is allowed for advanced callers who want to customize walking without going through the dataset.- Parameters:
backend (
HolonicStore) – AnyHolonicStoreimplementation. The resolver issues ASK, SELECT, and (indirectly via predicates) further ASK queries against the backend during resolution.registry_iri (
str) – IRI of the registry graph used for portal andcga:memberOfdiscovery. Predicates receive this IRI so they can query the registry if needed.
- resolve(predicate, from_holon, *, max_depth=3, order='network', limit=50)[source]
Walk the holarchy in BFS order and return predicate matches.
- Parameters:
predicate (
ResolvePredicate) – AResolvePredicateinstance. The starting holon and every neighbor visited during the walk is tested.from_holon (
str) – IRI of the starting holon.max_depth (
int) – Maximum BFS depth (hops fromfrom_holon). Clamped to the range[0, 100]to prevent runaway walks.max_depth=0tests only the starting holon.order (
Literal['network','reverse-network','containment']) – Walk topology:"network"(default),"reverse-network", or"containment".limit (
int) – Maximum number of matches to return. Clamped to[1, 10_000]. BFS terminates oncelimitis reached; remaining frontier holons are not visited.Returns
-------
list[ResolveMatch] – Matches in BFS order: all depth-0 matches first, then depth-1, etc. Within a single depth, order is determined by the backend’s
ORDER BY ?neighboron the walk query (IRI-alphabetical for deterministic tiebreaking).Examples
--------
holon:: (Network-proximity discovery from a known) –
from holonic import HolonicDataset, HasClassInInterior
ds = HolonicDataset() # … populate the holarchy …
- matches = ds.resolve(
HasClassInInterior(”urn:holonic:ontology:AgentHolon”), from_holon=”urn:holon:op-center”, max_depth=5,
) for m in matches:
print(f” {m.iri} distance={m.distance}”)
chain):: (Containment walk (governance) –
- matches = ds.resolve(
HasClassInInterior(”urn:ex:Person”), from_holon=”urn:holon:child”, order=”containment”,
)
predicate:: (Custom) –
from holonic import CustomSPARQL
- labeled = ds.resolve(
- CustomSPARQL(‘’’
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> ASK WHERE {
- GRAPH ?g {
<{holon_iri}> rdfs:label ?l . FILTER(STRSTARTS(?l, “B”))
}
}
’’’), from_holon=”urn:holon:root”,
)
Notes
-----
before (The starting holon itself is always tested (depth 0))
set (any neighbors are visited. Its inclusion in the result)
it. (depends solely on whether the predicate matches)
holon; (Predicates are evaluated exactly once per candidate)
internal (cycles in the walk topology are handled by an)
multiple (visited set. This means a holon reachable by)
record (paths contributes at most one ResolveMatch)
- Return type:
:param : :param carrying the shortest-path distance.:
ResolvePredicate is a typing.Protocol. Implementations
(HasClassInInterior, CustomSPARQL) are shown above. Custom
predicates need only a matches(backend, holon_iri, registry_iri) -> bool
method and an evidence() -> str method.
See HolonicDataset.resolve() for the driver.
Projection Pipelines (0.3.5)
- class holonic.ProjectionPipelineSpec(iri, name, steps=<factory>, description=None)[source]
Bases:
objectA named, ordered pipeline of projection steps.
Created in Python, registered into the holonic registry graph via
HolonicDataset.register_pipeline(). Once registered, holons attach to it viaattach_pipeline()and execution happens throughrun_projection().The
iriis the identity anchor of the spec in the registry; callers choose the IRI. A common convention isurn:projection:<name>orurn:holon:<holon>/pipeline/<name>.- Parameters:
iri (str)
name (str)
steps (list[ProjectionPipelineStep])
description (str | None)
- steps: list[ProjectionPipelineStep]
- class holonic.ProjectionPipelineStep(name, transform_name=None, construct_query=None)[source]
Bases:
objectOne step in a projection pipeline.
Either
transform_nameorconstruct_querymust be set. When both are present, the transform runs first, then the CONSTRUCT is applied to its output.transform_namerefers to an entry point in theholonic.projectionsgroup. Seeholonic.pluginsfor discovery and registration.
- class holonic.ProjectionPipelineSummary(iri, name, step_count=0, description=None)[source]
Bases:
objectLightweight pipeline descriptor for browser/list views.
Excludes step content to keep list queries cheap. Use
HolonicDataset.get_pipeline(iri)for the full detail.Forward-looking note: console integration should consume this for the pipelines-available-on-holon view.
See HolonicDataset.register_pipeline(), attach_pipeline(),
list_pipelines(), get_pipeline(), and run_projection() for the
driver surface.
Plugin System (0.3.5)
- class holonic.TransformNotFoundError[source]
Bases:
KeyErrorRaised when a pipeline references an unknown transform name.
- holonic.projection_transform(name)[source]
Register a Python function as a projection transform.
Intended for first-party transforms shipped in
holonic.projections. Third-party transforms declare themselves via theholonic.projectionsentry-point group in theirpyproject.toml.The decorator does not modify the function; it just records the name -> callable mapping in a module-level dict.
Example:
@projection_transform("strip_blank_nodes") def strip_blank_nodes(graph: Graph) -> Graph: ...
Pipelines reference the transform by the registered name:
ProjectionPipelineStep(name="strip", transform_name="strip_blank_nodes")
- holonic.resolve_transform(name)[source]
Return the callable for a registered transform name.
Raises
TransformNotFoundErrorif no transform with that name is registered.
- holonic.get_registered_transforms()[source]
Return all registered transforms: first-party + entry-points.
The first-party registry (populated by
@projection_transform) wins when names collide. This keeps the library’s own transforms stable even if a third-party package registers under the same name.
Third-party transforms register via the holonic.projections
entry-point group in their pyproject.toml:
[project.entry-points."holonic.projections"]
my_transform = "mypkg.transforms:my_transform"
First-party transforms register via the @projection_transform
decorator. Both are discovered by get_registered_transforms().
Projection Types
- class holonic.ProjectedGraph(nodes=<factory>, edges=<factory>)[source]
Bases:
objectAn LPG-style projection of an RDF graph.
Nodes have types and literal attributes collapsed onto them. Edges carry only object-property relationships. Blank nodes are resolved into inline structures where possible.
- Parameters:
nodes (dict[str, ProjectedNode])
edges (list[ProjectedEdge])
- nodes: dict[str, ProjectedNode]
- edges: list[ProjectedEdge]
- class holonic.ProjectedNode(iri, types=<factory>, attributes=<factory>, label=None)[source]
Bases:
objectA node in a projected graph with collapsed attributes.
- class holonic.ProjectedEdge(source, predicate, target, attributes=<factory>)[source]
Bases:
objectAn edge in a projected graph with collapsed attributes.
- class holonic.ProjectionPipeline(name='projection')[source]
Bases:
objectA composable pipeline of projection steps.
Steps are applied sequentially. Each step takes the output of the previous step as input. Steps can be SPARQL CONSTRUCTs (staying in RDF) or Python functions (Graph→Graph).
The final output can optionally be converted to a ProjectedGraph via project_to_lpg().
> TODO: write metadata about the Pipeline (self-describing) w/n holon boundary (new opaque portal type?)
Example:
```python pipeline = ProjectionPipeline(“visualization”) pipeline.add_construct(“strip_types”, CONSTRUCT_STRIP_TYPES, graph_iri=…) pipeline.add_construct(“labels”, CONSTRUCT_LABELS_ONLY, graph_iri=…) pipeline.add_transform(“custom”, my_transform_fn)
result_graph = pipeline.apply(source_graph) lpg = pipeline.apply_to_lpg(source_graph) ```
- steps: list[ProjectionStep]
- add_construct(name, template, graph_iri=None)[source]
Add a CONSTRUCT-based step.
- Return type:
- Parameters:
- add_transform(name, fn)[source]
Add a Python transform step (Graph→Graph).
- Return type:
- Parameters:
- apply_to_graph(source, backend=None)[source]
Apply all steps sequentially, returning the final Graph.
Alias for
apply()that matches the terminal-method naming used in SPEC R7.3 alongsideapply_to_lpg().
- Parameters:
name (str)
Backends
See backends.md for the full backend surface:
RdflibBackend (in-memory default), FusekiBackend (Apache Jena
Fuseki via SPARQL over HTTP), and guidance on implementing a custom
backend.