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', load_ontology=True, metadata_updates='eager')[source]

Bases: object

A 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; AbstractHolonicStore is 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_iri parameter configures the registry graph IRI.

  • 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.

__init__(backend=None, *, registry_iri='urn:holarchy:registry', 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.

  • 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 via refresh_metadata(). See docs/DECISIONS.md § D-0.3.3-2.

on_traversal(callback)[source]

Register a callback fired after each traverse().

The callback receives (source_iri, target_iri, projected, membrane_result) as arguments.

Added in version 0.7.0.

Return type:

None

on_validation(callback)[source]

Register a callback fired after each validate_membrane().

The callback receives (holon_iri, membrane_result).

Added in version 0.7.0.

Return type:

None

add_holon(iri, label, *, member_of=None, holon_type=None)[source]

Declare a holon in the registry. Returns the holon IRI.

Parameters:
  • iri (str) – The holon’s IRI.

  • label (str) – Human-readable label.

  • member_of (str | None) – IRI of the parent holon (holarchy containment).

  • holon_type (str | None) – Functional subtype to assert (e.g. "cga:DataHolon", "cga:AgentHolon"). Must be a prefixed CGA name or a full IRI. The holon always carries a cga:Holon; this adds a second rdf:type assertion.

  • Note

  • ----

  • cga (Depth is not stored -- it is derivable from the)

  • compute_depth(). (chain via)

Return type:

str

batch()[source]

Context manager that suppresses per-write metadata refresh.

Metadata refresh is deferred until the block exits, avoiding redundant computation during bulk writes. On normal exit, a single consolidated refresh runs for the registry. On exception, the original mode is restored without refreshing.

Nests safely: inner batch() blocks are no-ops when an outer batch is already active.

Example:

with ds.batch():
    for row in data:
        ds.add_holon(row["iri"], row["label"])
        ds.add_interior(row["iri"], row["ttl"])
# metadata refreshed once here

Added in version 0.6.0.

Return type:

_BatchContext

add_interior(holon_iri, ttl, *, graph_iri=None)[source]

Parse TTL into a named graph and register it as a holon’s interior.

Return type:

str

Parameters:
  • holon_iri (str)

  • ttl (str)

  • graph_iri (str | None)

add_boundary(holon_iri, ttl, *, graph_iri=None)[source]

Parse TTL into a named graph and register it as a holon’s boundary.

Return type:

str

Parameters:
  • holon_iri (str)

  • ttl (str)

  • graph_iri (str | None)

add_projection(holon_iri, ttl, *, graph_iri=None)[source]

Parse TTL into a named graph and register it as a holon’s projection.

Return type:

str

Parameters:
  • holon_iri (str)

  • ttl (str)

  • graph_iri (str | None)

add_context(holon_iri, ttl, *, graph_iri=None)[source]

Parse TTL into a named graph and register it as a holon’s context.

Return type:

str

Parameters:
  • holon_iri (str)

  • ttl (str)

  • graph_iri (str | None)

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

  • -------

  • boolTrue if the holon existed and was removed. False if 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:

bool

:param : rdfs:label, cga:memberOf) :param - All cga:hasInterior / hasBoundary / hasProjection: / hasContext bindings in the registry :param - The layer graphs themselves (via backend.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:ClassInstanceCount inventory

records – added by 0.3.3)

:paramcga:lastModified, cga:ClassInstanceCount inventory

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:

bool

update_portal(portal_iri, *, construct_query=<object object>, label=<object object>, portal_type=<object object>)[source]

Update a portal’s properties in-place.

Only the provided keyword arguments are changed; unspecified properties are preserved. The portal IRI and source/target holons are immutable (use remove + add to change those).

Parameters:
  • portal_iri (str) – IRI of the portal to update.

  • construct_query (str | None) – New CONSTRUCT query string, or None to remove it.

  • label (str | None) – New label, or None to remove it.

  • portal_type (str | None) – New RDF type (e.g. "cga:SealedPortal").

  • Raises

  • ------

  • ValueError – If the portal does not exist.

  • versionadded: (..) – 0.6.0:

Return type:

None

bulk_load(holons=None, portals=None)[source]

Create multiple holons and portals in a single batch.

Suppresses per-write metadata refresh during the batch and fires one consolidated refresh at the end. For holarchies with hundreds of holons, this is significantly faster than calling add_holon and add_portal in a loop.

Parameters:
  • holons (list[dict] | None) – List of dicts, each with keys matching add_holon() parameters: iri (required), label (required), and optionally member_of, holon_type.

  • portals (list[dict] | None) – List of dicts, each with keys matching add_portal() parameters: iri (required), source_iri (required), target_iri (required), and optionally construct_query, portal_type, extra_ttl, label.

  • Returns

  • -------

  • tuple[int – (holons_added, portals_added)

  • int] – (holons_added, portals_added)

  • Example

  • -------

  • ::

    ds.bulk_load(
    holons=[
    {“iri”: “urn:holon:a”, “label”: “A”,

    ”holon_type”: “cga:DataHolon”},

    {“iri”: “urn:holon:b”, “label”: “B”,

    ”member_of”: “urn:holon:a”},

    ], portals=[

    {“iri”: “urn:portal:ab”,

    ”source_iri”: “urn:holon:a”, “target_iri”: “urn:holon:b”, “construct_query”: “CONSTRUCT …”},

    ],

    )

  • versionadded: (..) – 0.5.0:

Return type:

tuple[int, int]

iter_holons(*, limit=None, offset=None)[source]

Yield holons via SPARQL against the registry.

Each holon is a fully-populated HolonInfo with layer graph IRIs resolved. Use this instead of list_holons() when iterating over large holarchies to avoid materializing the full list in memory.

Parameters:
  • limit (int | None) – Maximum number of holons to yield. None means no limit.

  • offset (int | None) – Number of holons to skip before yielding. None means 0.

  • Yields

  • ------

  • HolonInfo

  • versionadded: (..) – 0.5.0:

list_holons(*, limit=None, offset=None)[source]

Discover holons via SPARQL against the registry.

Returns a materialized list. For lazy iteration over large holarchies, use iter_holons() instead.

Parameters:
  • limit (int | None) – Maximum number of holons to return. None means all.

  • offset (int | None) – Number of holons to skip. None means 0.

Return type:

list[HolonInfo]

get_holon(holon_iri)[source]

Get info for a single holon, or None if not found.

Uses a direct filtered SPARQL query (5 queries total). O(1) in holarchy size.

Changed in version 0.6.0: Rewritten from linear scan to direct query.

Return type:

HolonInfo | None

Parameters:

holon_iri (str)

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 @prefix declarations – 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:

str

: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:

str

remove_portal(portal_iri)[source]

Remove a portal from the dataset.

Cleans up all triples with portal_iri as 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

  • -------

  • boolTrue if the portal existed and was removed. False if 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:

bool

iter_portals_from(source_iri, *, limit=None, offset=None)[source]

Yield portals originating from a holon.

Parameters:
  • limit (int | None) – Maximum number of portals to yield.

  • offset (int | None) – Number of portals to skip.

  • Yields

  • ------

  • PortalInfo

  • versionadded: (..) – 0.5.0:

  • source_iri (str)

find_portals_from(source_iri, *, limit=None, offset=None)[source]

Discover portals originating from a holon. Pure SPARQL.

Returns a materialized list. For lazy iteration, use iter_portals_from().

Return type:

list[PortalInfo]

Parameters:
  • source_iri (str)

  • limit (int | None)

  • offset (int | None)

iter_portals_to(target_iri, *, limit=None, offset=None)[source]

Yield portals targeting a holon.

Parameters:
  • limit (int | None) – Maximum number of portals to yield.

  • offset (int | None) – Number of portals to skip.

  • Yields

  • ------

  • PortalInfo

  • versionadded: (..) – 0.5.0:

  • target_iri (str)

find_portals_to(target_iri, *, limit=None, offset=None)[source]

Discover portals targeting a holon. Pure SPARQL.

Returns a materialized list. For lazy iteration, use iter_portals_to().

Return type:

list[PortalInfo]

Parameters:
  • target_iri (str)

  • limit (int | None)

  • offset (int | None)

find_portal(source_iri, target_iri)[source]

Find a direct portal between two holons. Returns None if none exists.

Return type:

PortalInfo | None

Parameters:
  • source_iri (str)

  • target_iri (str)

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:
  • source_iri (str)

  • target_iri (str)

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.

Raises SealedPortalError if the portal is a cga:SealedPortal – traversal is explicitly blocked regardless of whether the portal carries a CONSTRUCT query.

Parameters:
  • portal_iri (str) – IRI of the portal to traverse.

  • inject_into (str | None) – If provided, the resulting triples are also appended into this named graph in the dataset.

  • Returns

  • -------

  • rdflib.Graph – The projected triples.

Return type:

Graph

traverse(source_iri, target_iri, *, inject=True, validate=True, fail_on_breach=False, 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.

  • fail_on_breach (bool) – If True and validation returns COMPROMISED, roll back the injected triples and raise MembraneBreachError. Implies validate=True.

  • agent_iri (str | None) – If provided, record PROV-O provenance.

  • Returns

  • -------

  • (projected_graph

  • membrane_result_or_none)

Return type:

tuple[Graph, MembraneResult | None]

traverse_path(source_iri, target_iri, *, validate=True, fail_on_breach=False, agent_iri=None)[source]

Execute a multi-hop traversal along the shortest portal path.

Calls find_path() to discover the route, then executes traverse() for each hop in sequence. Each hop’s projected graph and membrane result are collected and returned.

Parameters:
  • source_iri (str) – Source and ultimate target holon IRIs.

  • target_iri (str) – Source and ultimate target holon IRIs.

  • validate (bool) – If True, validate the membrane at each hop.

  • fail_on_breach (bool) – If True and any hop produces COMPROMISED, raise MembraneBreachError immediately (remaining hops are not executed).

  • agent_iri (str | None) – If provided, record PROV-O provenance per hop.

  • Returns

  • -------

  • list[tuple[Graph – One entry per hop in the path.

  • None]] (MembraneResult |) – One entry per hop in the path.

  • Raises

  • ------

  • ValueError – If no path exists between source and target.

  • MembraneBreachError – If fail_on_breach=True and a hop produces COMPROMISED.

  • versionadded: (..) – 0.6.0:

Return type:

list[tuple[Graph, MembraneResult | None]]

dry_run(source_iri, target_iri)[source]

Simulate a traversal without mutating any state.

Runs the portal’s CONSTRUCT query, merges the result with the target’s existing interior(s) in a temporary graph, and validates against the target’s boundary shapes. Nothing is written to the dataset.

Useful for CI/CD validation of CONSTRUCT query changes, mapping updates, and interactive development.

Parameters:
  • source_iri (str) – Source and target holon IRIs.

  • target_iri (str) – Source and target holon IRIs.

  • Returns

  • -------

  • (projected_graph – The projected triples and what-if membrane validation.

  • membrane_result) – The projected triples and what-if membrane validation.

  • Raises

  • ------

  • ValueError – If no direct portal exists.

  • versionadded: (..) – 0.6.0:

Return type:

tuple[Graph, MembraneResult]

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:

MembraneResult

Parameters:

holon_iri (str)

validate_all()[source]

Validate membranes for all holons in the holarchy.

Returns a dict mapping holon IRI to its MembraneResult. Holons without boundary shapes still appear in the result (they will be INTACT with conforms=True).

Added in version 0.6.0.

Return type:

dict[str, MembraneResult]

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.

Return type:

str

Parameters:
  • portal_iri (str)

  • source_iri (str)

  • target_iri (str)

  • agent_iri (str)

  • context_graph (str | None)

record_validation(holon_iri, health, agent_iri, *, context_graph=None)[source]

Record a membrane validation as a PROV-O Activity.

Return type:

str

Parameters:
collect_audit_trail(*, limit=None, offset=None, since=None, kind=None)[source]

Collect the 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.

Parameters:
  • limit (int | None) – Maximum number of activities to return. None means all.

  • offset (int | None) – Number of activities to skip. None means 0.

  • since (str | None) – ISO-8601 timestamp. Only return activities started after this time. Pushed to the SPARQL engine via FILTER.

  • kind (str | None) – Filter by activity type: 'traversal' or 'validation'. None means both.

  • Returns

  • -------

  • AuditTrail

  • versionchanged: (..) – 0.7.0: Added limit, offset, since, kind.

Return type:

AuditTrail

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.

Return type:

str

Parameters:
  • holon_iri (str)

  • alignment_iris (list[str] | None)

query(sparql, **bindings)[source]

Run a SELECT query against the full dataset.

Return type:

list[dict[str, Any]]

Parameters:

sparql (str)

construct(sparql, **bindings)[source]

Run a CONSTRUCT query against the full dataset.

Return type:

Graph

Parameters:

sparql (str)

update(sparql)[source]

Run a SPARQL UPDATE against the dataset.

Return type:

None

Parameters:

sparql (str)

project_holon(holon_iri, *, store_as=None, **lpg_kwargs)[source]

Project a holon’s interior(s) into an LPG-style structure.

Ad-hoc structural projection: merges all interior graphs, runs project_to_lpg() for type/literal/blank-node collapse, and returns a ProjectedGraph. No pipeline spec is needed and no PROV-O activity is recorded.

For governed, auditable projections with provenance, use run_projection() with a registered ProjectionPipelineSpec instead.

Parameters:
  • holon_iri (str) – The holon to project.

  • store_as (str | None) – If provided, serialize the LPG back to triples and store in this named graph (registered as a projection layer).

  • **lpg_kwargs – Forwarded to project_to_lpg() – collapse_types, resolve_blanks, etc.

  • Returns

  • -------

  • ProjectedGraph

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).

Parameters:
  • holon_iri (str) – The holon whose interiors to project.

  • pipeline – A ProjectionPipeline instance.

  • store_as (str | None) – If provided, store the result as a named graph.

  • Returns

  • -------

  • rdflib.Graph

Return type:

Graph

compose(holon_iris, *, layers=None)[source]

Union interior graphs across multiple holons into one view.

Returns a merged rdflib.Graph containing all triples from the requested layers of the specified holons. Does not persist the result; callers can serialize or query it directly.

Parameters:
  • holon_iris (list[str]) – List of holon IRIs to compose.

  • layers (list[str] | None) – Which layer types to include. Defaults to ["interior"]. Valid values: "interior", "projection", "boundary", "context".

  • Returns

  • -------

  • rdflib.Graph – Merged graph.

  • versionadded: (..) – 0.6.0:

Return type:

Graph

holarchy_summary(*, max_age=None, recent_limit=10)[source]

Return an aggregated health snapshot of the holarchy.

Collects holon/portal counts, root count, membrane health distribution, staleness count, and recent activities in a single call. Designed for dashboards that need a consolidated overview without making 4+ separate SPARQL round-trips.

Parameters:
  • max_age (timedelta | None) – Staleness threshold. Defaults to 1 hour.

  • recent_limit (int) – Number of recent activities to include.

  • Returns

  • -------

  • HolarchySummary

  • versionadded: (..) – 0.7.0:

export_graph(graph_iri, format='turtle')[source]

Serialize a single named graph to a string.

Parameters:
  • graph_iri (str) – IRI of the named graph to export.

  • format (str) – RDF serialization format. Common values: "turtle", "xml", "json-ld", "nt" (N-Triples). Passed directly to rdflib’s Graph.serialize().

  • Returns

  • -------

  • str – The serialized graph content.

  • Raises

  • ------

  • ValueError – If the graph does not exist.

  • versionadded: (..) – 0.5.0:

Return type:

str

export(format='trig')[source]

Serialize the entire dataset (all named graphs) to a string.

Parameters:
  • format (str) – RDF serialization format that supports named graphs. Common values: "trig" (default), "nquads". Single-graph formats like "turtle" will lose graph boundaries.

  • Returns

  • -------

  • str – The serialized dataset content.

  • Example

  • -------

  • ::

    # Save to file with open(“holarchy.trig”, “w”) as f:

    f.write(ds.export())

    # Or export as N-Quads nquads = ds.export(format=”nquads”)

  • versionadded: (..) – 0.5.0:

Return type:

str

summary()[source]

Human-readable summary of the holarchy state.

Return type:

str

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.

Parameters:
  • holon_iri (str | None) – If provided, compute depth for a single holon. If None, compute for all holons.

  • Returns

  • -------

  • HolarchyTree – Dict-like object (tree[iri] -> depth) that also carries parent/child relationships and labels. print(tree) renders the holarchy as an indented tree.

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:

list[HolonSummary]

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:

HolonDetail | None

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:

list[ClassInstanceCount]

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:

NeighborhoodGraph

Parameters:
list_portals()[source]

Return a flat list of all portals across the dataset.

Return type:

list[PortalSummary]

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:

PortalDetail | None

Parameters:

portal_iri (str)

portal_traversal_history(portal_iri, limit=50)[source]

Return recorded traversals attributable to a single portal.

See note in sparql.py PORTAL_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:

list[TraversalRecord]

Parameters:
  • portal_iri (str)

  • limit (int)

get_activity(activity_iri)[source]

Look up a single provenance activity by IRI.

Returns a TraversalRecord if the activity has prov:used and prov:generated predicates (indicating a portal traversal), a ValidationRecord if it has cga:validatedHolon, or None if not found.

Added in version 0.7.0.

Return type:

TraversalRecord | ValidationRecord | None

Parameters:

activity_iri (str)

last_traversal(holon_iri)[source]

Return the most recent traversal targeting a given holon.

Unlike portal_traversal_history() (which requires knowing the portal IRI), this finds the latest traversal into holon_iri regardless of which portal was used.

Returns None if no traversal has been recorded.

Added in version 0.6.0.

Return type:

TraversalRecord | None

Parameters:

holon_iri (str)

freshness(holon_iri)[source]

Return time since the most recent traversal into this holon.

Returns None if no traversal has been recorded.

Added in version 0.6.0.

Return type:

timedelta | None

Parameters:

holon_iri (str)

is_stale(holon_iri, max_age=None)[source]

Check whether a holon’s data is stale.

Parameters:
  • holon_iri (str) – The holon to check.

  • max_age (timedelta | None) – Maximum acceptable age. Defaults to 1 hour.

  • if (Returns True if the holon has never been traversed or)

  • max_age. (freshness() exceeds)

  • versionadded: (..) – 0.6.0:

Return type:

bool

stale_holons(max_age=None)[source]

Return all holons whose data is stale.

Parameters:
  • max_age (timedelta | None) – Maximum acceptable age. Defaults to 1 hour.

  • versionadded: (..) – 0.6.0:

Return type:

list[HolonInfo]

derivation_chain(holon_iri)[source]

Return upstream holon IRIs in derivation order.

Walks the prov:wasDerivedFrom chain backward from holon_iri to find all holons that contributed data (directly or transitively) via portal traversals. Returns a list of holon IRIs (most direct source first).

Added in version 0.6.0.

Return type:

list[str]

Parameters:

holon_iri (str)

rollback_traversal(activity_iri)[source]

Undo a traversal by removing the triples it injected.

Looks up the target holon from the provenance activity, re-runs the portal’s CONSTRUCT query to reconstruct what was injected, and removes those triples from the target interior.

Parameters:
  • activity_iri (str) – IRI of the prov:Activity to roll back.

  • Returns

  • -------

  • int – Number of triples removed.

  • versionadded: (..) – 0.6.0:

Return type:

int

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() or backend.update().

Returns the refreshed per-graph metadata in the order returned by the registry’s cga:hasLayer enumeration.

Return type:

list[GraphMetadata]

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:

int

get_graph_metadata(graph_iri)[source]

Return currently-materialized metadata for a graph.

Returns None if no metadata has been written. Use refresh_metadata() to materialize it.

Return type:

GraphMetadata | None

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 ResolvePredicate instance (HasClassInInterior, CustomSPARQL, or any object with the predicate protocol from holonic.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:memberOf walk).

  • limit (int) – Maximum number of matches. Clamped to [1, 10_000].

  • Returns

  • -------

  • list[ResolveMatch] – Matches in BFS depth order. See holonic.scope for 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. Raises TransformNotFoundError at registration time rather than later at run time.

Returns the pipeline’s IRI.

Return type:

str

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:ProjectionPipelineStep vocabulary and for valid rdf:List ordering.

Return type:

None

Parameters:

ttl (str)

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).

Return type:

None

Parameters:
  • holon_iri (str)

  • spec_iri (str)

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:

list[ProjectionPipelineSummary]

Parameters:

holon_iri (str)

get_pipeline(spec_iri)[source]

Return the full pipeline spec as a ProjectionPipelineSpec.

Returns None if no pipeline with the given IRI is registered. Steps are returned in their declared rdf:List order.

Return type:

ProjectionPipelineSpec | None

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.

Governed projection: merges the holon’s interior graphs, runs each step of the referenced ProjectionPipelineSpec in declared order (Python transform first, then inline CONSTRUCT if present), and optionally stores the result as a named graph registered as a projection layer. Records a full prov:Activity in the holon’s context graph with transform versions, host metadata, and timing.

This is distinct from project_holon(), which is an ad-hoc structural projection with no pipeline spec and no provenance. Use project_holon for quick interactive exploration; use run_projection for governed, auditable workflows.

Parameters:
  • holon_iri (str) – The holon whose interiors are projected.

  • spec_iri (str) – IRI of a registered ProjectionPipelineSpec.

  • store_as (str | None) – Named graph IRI to store the projection result in.

  • agent_iri (str | None) – Agent to associate with the provenance activity.

  • recorded (Provenance)

  • -------------------

  • <spec_iri> (- prov:used)

  • store_as) (- prov:generated <output_graph_iri> (if)

  • prov:endedAtTime (- prov:startedAtTime /)

  • provided) (- prov:wasAssociatedWith <agent_iri> (if)

  • used (- cga:transformVersion for each transform)

  • cga:runHost (-) – cga:runHolonicVersion

  • cga:runPlatformcga:runHolonicVersion

  • cga:runPythonVersioncga:runHolonicVersion

Return type:

Graph

:param : cga:runHolonicVersion :param Raises: :param ——: :param ValueError: If spec_iri is not registered. :param TransformNotFoundError: If 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.

Ergonomics (0.5.0)

Subtype assertion. add_holon(iri, label, holon_type="cga:DataHolon") asserts the functional subtype at creation time without raw SPARQL.

Generators with pagination. iter_holons(limit=, offset=), iter_portals_from(iri, limit=, offset=), and iter_portals_to(iri, limit=, offset=) yield results lazily. The list_holons() and find_portals_*() methods delegate to these generators and also accept limit/offset.

Bulk load. bulk_load(holons=[...], portals=[...]) creates multiple holons and portals in a single batch with one metadata refresh at the end.

Export. export_graph(iri, format='turtle') serializes a single named graph; export(format='trig') serializes the entire dataset. Common formats: turtle, trig, nquads, json-ld, xml.

Serialization. All model and console-model dataclasses provide to_dict() for JSON-ready serialization. Enum values are automatically converted to their string value.

Typing. The library ships a py.typed marker file. Downstream consumers using mypy or pyright get full type-checking support.

Governance & Safety (0.6.0)

Fail-closed traversal. traverse(fail_on_breach=True) validates the target membrane after injection. If COMPROMISED, the target interior is restored from a pre-injection snapshot and MembraneBreachError is raised. The target is left unchanged.

Dry-run simulation. dry_run(source, target) runs the portal’s CONSTRUCT, merges with the target’s existing interior in memory, and validates against boundary shapes. Nothing is written to the dataset.

Multi-hop traversal. traverse_path(source, target) discovers the shortest portal path and executes traverse() for each hop. Supports fail_on_breach and provenance recording per hop.

Sealed portals. SealedPortalError is raised when traversal is attempted on a cga:SealedPortal. Use update_portal(portal_type= "cga:SealedPortal") to seal a portal without removing it.

Batch validation. validate_all() validates every holon’s membrane and returns dict[str, MembraneResult].

Portal update. update_portal(iri, construct_query=, label=, portal_type=) updates portal properties in-place.

Composition. compose([holon_iris], layers=) unions interior graphs across multiple holons into one queryable rdflib.Graph.

Provenance helpers. last_traversal(holon_iri) returns the most recent TraversalRecord. derivation_chain(holon_iri) walks prov:wasDerivedFrom backward to list upstream holons.

Rollback. rollback_traversal(activity_iri) undoes a traversal by re-running the portal’s CONSTRUCT and removing the projected triples from the target interior.

Staleness tracking. freshness(holon_iri) returns a timedelta since the last traversal. is_stale(holon_iri, max_age=) returns a boolean. stale_holons(max_age=) returns all stale holons.

Source layer scoping. Portal CONSTRUCTs default to projection scope when projections exist (prevents PII leaking from raw interiors). Force full-dataset access via cga:sourceLayer cga:InteriorRole on the portal.

Batch context manager. with ds.batch(): suppresses per-write metadata refresh and fires one consolidated refresh on exit.

Input validation. All add_* methods validate IRIs at the API boundary via _validate_iri(). Labels are escaped via _escape_ttl() to prevent Turtle injection.

Consumer Integration (0.7.1)

Paginated audit trail. collect_audit_trail(limit=, offset=, since=, kind=) pushes filtering to the SPARQL engine via ORDER BY DESC(?timestamp) LIMIT/OFFSET. Calling with no arguments returns the full trail (backward compatible).

Activity lookup. get_activity(activity_iri) returns a TraversalRecord or ValidationRecord for a single provenance activity. Eliminates the O(all) scan through collect_audit_trail().

SPARQL classification. classify_sparql(query) returns the query form ('select', 'ask', 'construct', 'describe', 'update'). Strips comments and string literals before matching.

IRI validation. validate_iri(iri) is the public entry point to the library’s IRI validation. Raises ValueError for unsafe characters.

Dashboard summary. holarchy_summary(max_age=, recent_limit=) returns a HolarchySummary with holon count, portal count, root count, health distribution, staleness count, and recent activities.

Notification hooks. on_traversal(callback) and on_validation(callback) register callbacks that fire synchronously after each traverse() or validate_membrane(). Eliminates polling for same-process event detection.

Structured violations. ShapeViolation dataclass with shape_iri, focus_node, path, value, message, severity. MembraneResult.shape_violations carries a list[ShapeViolation] populated from the pyshacl report graph.

Store Protocol (0.4.0)

class holonic.HolonicStore(*args, **kwargs)[source]

Bases: Protocol

Mandatory 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 inherits AbstractHolonicStore. 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 @abstractmethod enforcement (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 by isinstance(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.

graph_exists(graph_iri)[source]

Return True if the named graph contains at least one triple.

Return type:

bool

Parameters:

graph_iri (str)

get_graph(graph_iri)[source]

Return the named graph as an rdflib.Graph (for local processing).

Return type:

Graph

Parameters:

graph_iri (str)

put_graph(graph_iri, g)[source]

Replace the named graph with the contents of g.

Return type:

None

Parameters:
post_graph(graph_iri, g)[source]

Append triples from g into the named graph.

Return type:

None

Parameters:
delete_graph(graph_iri)[source]

Delete the named graph entirely.

Return type:

None

Parameters:

graph_iri (str)

parse_into(graph_iri, data, format='turtle')[source]

Parse serialized RDF into the named graph (append).

Return type:

None

Parameters:
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.

Return type:

list[dict[str, Any]]

Parameters:
construct(sparql, **bindings)[source]

Execute a CONSTRUCT query. Return results as an rdflib.Graph.

Return type:

Graph

Parameters:
ask(sparql, **bindings)[source]

Execute an ASK query. Return boolean.

Return type:

bool

Parameters:
update(sparql)[source]

Execute a SPARQL UPDATE (INSERT/DELETE/DROP/CREATE).

Return type:

None

Parameters:

sparql (str)

list_named_graphs()[source]

Return IRIs of all named graphs containing triples.

Return type:

list[str]

class holonic.AbstractHolonicStore[source]

Bases: ABC

Abstract 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 | None recompute per-graph metadata (triple count, class inventory, last-modified timestamp) natively. The library’s MetadataRefresher.refresh_graph dispatches 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.

Return type:

bool

Parameters:

graph_iri (str)

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.Graph rather than raise.

Return type:

Graph

Parameters:

graph_iri (str)

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.

Return type:

None

Parameters:
abstractmethod post_graph(graph_iri, g)[source]

Append the triples in g to 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).

Return type:

None

Parameters:
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.

Return type:

None

Parameters:

graph_iri (str)

abstractmethod parse_into(graph_iri, data, format='turtle')[source]

Parse serialized RDF and append into the named graph.

format is an rdflib parser name; common values are "turtle", "xml", "n3", "json-ld", "nquads". Semantic equivalent to post_graph(graph_iri, rdflib.Graph().parse(data=data, format=format)) but implementations MAY optimize (e.g. stream-parse into the backing store directly).

Return type:

None

Parameters:
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, datetime objects for xsd:dateTime) and strings for IRIs.

bindings is reserved for future parameterized-query support; implementations MAY raise NotImplementedError on non-empty bindings in 0.4.x.

Return type:

list[dict[str, Any]]

Parameters:
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 use put_graph or post_graph.

bindings: see query.

Return type:

Graph

Parameters:
abstractmethod ask(sparql, **bindings)[source]

Execute a SPARQL ASK query.

Returns True if the query has at least one solution, False otherwise. bindings: see query.

Return type:

bool

Parameters:
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, call HolonicDataset.refresh_metadata after out-of-band updates to reconcile.

Return type:

None

Parameters:

sparql (str)

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.

Return type:

list[str]

The GraphBackend alias was removed in 0.5.0. Use HolonicStore. See docs/MIGRATION.md.

Model Types

class holonic.HolonInfo(iri, label=None, interior_graphs=<factory>, boundary_graphs=<factory>, projection_graphs=<factory>, context_graphs=<factory>)[source]

Bases: _DictMixin

Descriptor for a discovered holon.

Parameters:
iri: str
label: str | None = None
interior_graphs: list[str]
boundary_graphs: list[str]
projection_graphs: list[str]
context_graphs: list[str]
class holonic.PortalInfo(iri, source_iri, target_iri, label=None, construct_query=None, portal_type=None)[source]

Bases: _DictMixin

Descriptor for a discovered portal.

Parameters:
  • iri (str)

  • source_iri (str)

  • target_iri (str)

  • label (str | None)

  • construct_query (str | None)

  • portal_type (str | None)

iri: str
source_iri: str
target_iri: str
label: str | None = None
construct_query: str | None = None
portal_type: str | None = None
class holonic.MembraneResult(holon_iri, conforms, health, report_text, violations=<factory>, warnings=<factory>, shape_violations=<factory>)[source]

Bases: _DictMixin

Result of SHACL membrane validation.

Parameters:
holon_iri: str
conforms: bool
health: MembraneHealth
report_text: str
violations: list[str]
warnings: list[str]
shape_violations: list[ShapeViolation]
summary()[source]

Return a summary of the Holon’s Membrane.

Return type:

str

property is_healthy: bool

True when the membrane is INTACT, False otherwise.

Convenience property so callers don’t need to import MembraneHealth for a simple boolean check.

Added in version 0.6.0.

class holonic.MembraneHealth(*values)[source]

Bases: Enum

Classes of health for a Holon Membrane.

INTACT = 'intact'
WEAKENED = 'weakened'
COMPROMISED = 'compromised'
class holonic.MembraneBreachError(result)[source]

Bases: Exception

Raised 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: _DictMixin

Summary of what a holon’s boundary requires (from SHACL shapes).

Parameters:
holon_iri: str
target_classes: list[str]
required_fields: list[str]
optional_fields: list[str]
violations: int = 0
warnings: int = 0
class holonic.AuditTrail(traversals=<factory>, validations=<factory>, derivation_chain=<factory>, surfaces=<factory>)[source]

Bases: _DictMixin

Complete provenance audit of all traversals and validations.

Parameters:
traversals: list[TraversalRecord]
validations: list[ValidationRecord]
derivation_chain: list[tuple[str, str]]
surfaces: dict[str, SurfaceReport]
property participating_holons: set[str]

All holon IRIs involved in the audit trail.

validation_for(holon_iri)[source]

Find the most recent validation for a holon.

Return type:

ValidationRecord | None

Parameters:

holon_iri (str)

summary()[source]

Return a summary report for the AuditTrail.

Return type:

str

class holonic.TraversalRecord(activity_iri, source_iri, target_iri, agent_iri=None, portal_label=None, timestamp=None)[source]

Bases: _DictMixin

A single portal traversal event from the provenance trail.

Parameters:
  • activity_iri (str)

  • source_iri (str)

  • target_iri (str)

  • agent_iri (str | None)

  • portal_label (str | None)

  • timestamp (str | None)

activity_iri: str
source_iri: str
target_iri: str
agent_iri: str | None = None
portal_label: str | None = None
timestamp: str | None = None
property source_label: str

Opinionated iri-derived source label.

property target_label: str

Opinionated iri-derived target label.

class holonic.ValidationRecord(activity_iri, holon_iri, health, agent_iri=None, timestamp=None)[source]

Bases: _DictMixin

A membrane validation event from the provenance trail.

Parameters:
  • activity_iri (str)

  • holon_iri (str)

  • health (str)

  • agent_iri (str | None)

  • timestamp (str | None)

activity_iri: str
holon_iri: str
health: str
agent_iri: str | None = None
timestamp: str | None = None
property health_label: str

Return holon health label.

property holon_label: str

Return opinionated label based on holon iri.

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: _DictMixin

Lightweight 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:
  • iri (str)

  • label (str | None)

  • kind (str | None)

  • classification (str | None)

  • member_of (str | None)

  • interior_triple_count (int | None)

  • health (str | None)

iri: str
label: str | None = None
kind: str | None = None
classification: str | None = None
member_of: str | None = None
interior_triple_count: int | None = None
health: str | None = None

Holon, or ‘Holon’ if none.

Type:

The most-specific rdf

Type:

type other than cga

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: _DictMixin

Full holon descriptor including layer graph IRIs and registry triples.

Parameters:
iri: str
label: str | None = None
kind: str | None = None
classification: str | None = None
member_of: str | None = None
interior_graphs: list[str]
boundary_graphs: list[str]
projection_graphs: list[str]
context_graphs: list[str]
interior_triple_count: int | None = None
health: str | None = None
layer_metadata: dict[str, GraphMetadata]
holon_last_modified: str | None = None

Per-graph metadata keyed by graph IRI. Populated when the registry has materialized metadata (see HolonicDataset.refresh_metadata). Empty dict if metadata_updates=”off” and no explicit refresh has been called. Added 0.3.3.

class holonic.ClassInstanceCount(class_iri, count)[source]

Bases: _DictMixin

Count of instances of a single rdf:type within a holon’s interior.

Parameters:
class_iri: str
count: int
class holonic.NeighborhoodNode(key, label=None, kind=None, health=None, triples=0, size=10.0, node_type='holon')[source]

Bases: _DictMixin

Stores metadata about a node in a neighborhood subgraph.

Parameters:
key: str
label: str | None = None
kind: str | None = None
health: str | None = None
triples: int = 0
size: float = 10.0
node_type: str = 'holon'
class holonic.NeighborhoodEdge(key, source, target, edge_type, label=None, health=None, size=1.0)[source]

Bases: _DictMixin

Stores metadata about an edge in a neighborhood subgraph.

Parameters:
key: str
source: str
target: str
edge_type: str
label: str | None = None
health: str | None = None
size: float = 1.0
class holonic.NeighborhoodGraph(source_holon, depth, nodes=<factory>, edges=<factory>)[source]

Bases: _DictMixin

A 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]
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.md of the holonic-console project.

Return type:

dict

class holonic.PortalSummary(iri, source_iri, target_iri, label=None, portal_type=None, last_traversal=None, health=None)[source]

Bases: _DictMixin

Lightweight portal descriptor for browser/list views.

Parameters:
  • iri (str)

  • source_iri (str)

  • target_iri (str)

  • label (str | None)

  • portal_type (str | None)

  • last_traversal (str | None)

  • health (str | None)

iri: str
source_iri: str
target_iri: str
label: str | None = None
portal_type: str | None = None
last_traversal: str | None = None
health: str | None = None

ISO-8601 timestamp of the most-recent recorded traversal.

class holonic.PortalDetail(iri, source_iri, target_iri, label=None, portal_type=None, construct_query=None, graph_iri=None)[source]

Bases: _DictMixin

Full portal descriptor including the CONSTRUCT query body.

Parameters:
  • iri (str)

  • source_iri (str)

  • target_iri (str)

  • label (str | None)

  • portal_type (str | None)

  • construct_query (str | None)

  • graph_iri (str | None)

iri: str
source_iri: str
target_iri: str
label: str | None = None
portal_type: str | None = None
construct_query: str | None = None
graph_iri: str | None = None

Named graph in which this portal is registered (the source’s boundary).

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: _DictMixin

Per-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. Call HolonicDataset.refresh_metadata() after out-of-band writes.

last_modified is UTC; refreshed_at is the time the current row was written (may be later than last_modified if a refresh ran without a content change).

Parameters:
iri: str
triple_count: int = 0
last_modified: str | None = None
refreshed_at: str | None = None
class_inventory: list[ClassInstanceCount]
graph_role: str | None = None

ISO 8601 UTC datetime, microsecond precision. None if never written.

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: object

A 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).

iri: str
distance: int
evidence: str = ''
Parameters:
class holonic.HasClassInInterior(class_iri)[source]

Bases: object

Match 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,

    )

class_iri: str
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:

bool

Parameters:
evidence()[source]

Return a description naming the class being matched.

Return type:

str

class holonic.CustomSPARQL(ask_template)[source]

Bases: object

Match 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 uses str.replace, not str.format, so normal SPARQL braces in GRAPH ?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 cga:Confidential .

    }

    }

    ’’’)

  • 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)

ask_template: str
matches(backend, holon_iri, registry_iri)[source]

Substitute placeholders and run the ASK query against the backend.

Uses str.replace for substitution, not str.format, so SPARQL braces in the template body don’t need escaping.

Return type:

bool

Parameters:
evidence()[source]

Return the first line of the ASK template as a terse description.

Return type:

str

class holonic.ScopeResolver(backend, registry_iri)[source]

Bases: object

Executes a scoped BFS walk against a backend.

Held by HolonicDataset and delegated to from resolve(). Public construction is allowed for advanced callers who want to customize walking without going through the dataset.

Parameters:
  • backend (HolonicStore) – Any HolonicStore implementation. 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 and cga:memberOf discovery. 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) – A ResolvePredicate instance. 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 from from_holon). Clamped to the range [0, 100] to prevent runaway walks. max_depth=0 tests 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 once limit is 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 ?neighbor on 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:

list[ResolveMatch]

: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: _DictMixin

A 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 via attach_pipeline() and execution happens through run_projection().

The iri is the identity anchor of the spec in the registry; callers choose the IRI. A common convention is urn:projection:<name> or urn:holon:<holon>/pipeline/<name>.

Parameters:
iri: str
name: str
steps: list[ProjectionPipelineStep]
description: str | None = None
class holonic.ProjectionPipelineStep(name, transform_name=None, construct_query=None)[source]

Bases: _DictMixin

One step in a projection pipeline.

Either transform_name or construct_query must be set. When both are present, the transform runs first, then the CONSTRUCT is applied to its output.

transform_name refers to an entry point in the holonic.projections group. See holonic.plugins for discovery and registration.

Parameters:
  • name (str)

  • transform_name (str | None)

  • construct_query (str | None)

name: str
transform_name: str | None = None
construct_query: str | None = None
class holonic.ProjectionPipelineSummary(iri, name, step_count=0, description=None)[source]

Bases: _DictMixin

Lightweight 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.

Parameters:
  • iri (str)

  • name (str)

  • step_count (int)

  • description (str | None)

iri: str
name: str
step_count: int = 0
description: str | None = None

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: KeyError

Raised 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 the holonic.projections entry-point group in their pyproject.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")
Return type:

Callable[[Callable[[Graph], Graph]], Callable[[Graph], Graph]]

Parameters:

name (str)

holonic.resolve_transform(name)[source]

Return the callable for a registered transform name.

Raises TransformNotFoundError if no transform with that name is registered.

Return type:

Callable[[Graph], Graph]

Parameters:

name (str)

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.

Return type:

dict[str, Callable[[Graph], Graph]]

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: object

An 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]
to_dict()[source]

Serialize to a plain dict (JSON-serializable).

Return type:

dict

class holonic.ProjectedNode(iri, types=<factory>, attributes=<factory>, label=None)[source]

Bases: object

A node in a projected graph with collapsed attributes.

Parameters:
iri: str
types: list[str]
attributes: dict[str, Any]
label: str | None = None
class holonic.ProjectedEdge(source, predicate, target, attributes=<factory>)[source]

Bases: object

An edge in a projected graph with collapsed attributes.

Parameters:
source: str
predicate: str
target: str
attributes: dict[str, Any]
class holonic.ProjectionPipeline(name='projection')[source]

Bases: object

A 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:

ProjectionPipeline

Parameters:
  • name (str)

  • template (str)

  • graph_iri (str | None)

add_transform(name, fn)[source]

Add a Python transform step (Graph->Graph).

Return type:

ProjectionPipeline

Parameters:
apply(source, backend=None)[source]

Apply all steps sequentially, returning the final Graph.

Return type:

Graph

Parameters:

source (Graph)

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 alongside apply_to_lpg().

Return type:

Graph

Parameters:

source (Graph)

apply_to_lpg(source, backend=None, **lpg_kwargs)[source]

Apply all steps, then convert the result to an LPG projection.

Return type:

ProjectedGraph

Parameters:

source (Graph)

Parameters:

name (str)

class holonic.ProjectionStep(name, construct=None, transform=None)[source]

Bases: object

A single step in a projection pipeline.

Parameters:
name: str
construct: str | None = None
transform: Callable[[Graph], Graph] | None = None
apply(source, backend=None)[source]

Apply this step to a source graph.

Return type:

Graph

Parameters:

source (Graph)

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.