Holonic Four-Graph Layer¶
Native implementation of Kurt Cagle's holonic knowledge-graph model (after Koestler's holon concept) on top of named graphs. Each entity is a single IRI that binds four graphs — Interior / Boundary / Context / Meta — and SHACL shapes in the boundary graph act as a formal membrane: a violation is not "bad data" to be cleaned up but a circuit-breaker signal that downstream RAG paths consult to demote or block the holon.
The implementation lives in the indentiagraph-holonic crate and
is mounted by the server under /holonic/* when explicitly
enabled. It ships with its own Axum router, its own SHACL
validation entry point, and a backing store that proxies SPARQL
to the live dataset.
Opt-in configuration¶
Holonic is not on by default. Two equivalent activation paths:
The server calls AppState::enable_holonic(default_tenant) at
start-up. This:
- Builds a
SwarmHolonicStorebound to the sameSwarmDatasetas the rest of the server. - Bootstraps the CGA T-Box (
cga.ttl) into the shared ontology named graph idempotently. - Mounts the
/holonic/*router under the main Axum app. - Adds
/holonic/healthto the authentication bypass list so orchestrators can probe readiness without credentials.
Startup guards¶
Both guards fail at startup, not on first request, so a misconfiguration surfaces before any traffic arrives.
Cluster-mode refused¶
enable_holonic errors out immediately when a ClusterManager
is attached to the state:
holonic service cannot run under the Raft cluster manager yet;
writes would diverge from followers. Disable holonic or run
standalone (see SwarmHolonicStore cluster-mode TODO).
Holonic writes intentionally bypass the UpdateExecutor path
used by /update; in cluster mode this would diverge from
followers. Run the node standalone for holonic ingest, or extend
SwarmHolonicStore::update with a Raft proposal path before
enabling both.
Empty tenant refused¶
An empty default tenant would collapse every ?tenant=-less
request into a single registry graph shared across deployments.
Provide a concrete slug (typically _ for a shared reference
tenant, or a per-deployment tenant ID).
Readiness contract¶
GET /holonic/health is always mounted — regardless of
whether enable_holonic succeeded. Clients get a stable contract:
| Status | Meaning |
|---|---|
200 + JSON |
Holonic service attached; body is {"available": true, "default_tenant": "..."} |
503 |
Holonic is not configured on this server |
The endpoint is in the server's AUTH_BYPASS_PATHS, so
Kubernetes probes, ArgoCD health checks, and external monitoring
can poll it without credentials.
Endpoints¶
| Method | Path | Purpose |
|---|---|---|
GET |
/holonic/health |
Readiness probe (200/503) |
POST |
/holonic/holons?tenant=… |
Declare a holon in the tenant registry graph |
GET |
/holonic/holons?tenant=… |
List holons with interior/boundary counts |
GET |
/holonic/holons/{iri}?tenant=… |
Detail for one holon, including every layer |
POST |
/holonic/holons/{iri}/interior |
Add interior A-Box triples (per source) |
POST |
/holonic/holons/{iri}/boundary |
Inject SHACL shapes as the holon's membrane |
POST |
/holonic/holons/{iri}/context |
Add context / PROV-O events |
POST |
/holonic/holons/{iri}/projection |
Add a projection layer |
POST |
/holonic/portals |
Register a cga:TransformPortal |
GET |
/holonic/portals?source=… |
List outbound portals from a holon |
GET |
/holonic/depth?holon=… |
Compute holarchy depth |
All POST bodies use JSON with a turtle: string field for
RDF payloads (except add_holon / add_portal, which take
structured fields directly). The tenant= query parameter
defaults to HOLONIC_DEFAULT_TENANT when omitted.
Authorization¶
When an AuthenticationService is configured, the /holonic/*
router sits behind a dedicated middleware that enforces:
- Anonymous callers are rejected with 401 on every endpoint
(except
/holonic/health, which is in the auth-bypass list). This holds even in deployments where the base authn layer accepts anonymous actors for other routes. GET/HEADrequirePermission::Read; a caller withPermission::Nonegets 403.POST/PUT/PATCH/DELETErequirePermission::Write. Writes with authn configured but no authz service also return 403 — the operator clearly wanted credentials enforced but has not yet attached the permission layer.- Cross-tenant
?tenant=mismatches are audit-logged under theholonic.authztracing target with the actor's org-scope slug and the requested tenant. Blocking (rather than logging) requires a canonical tenant claim onActor, which is tracked in a follow-up ADR.
In dev / standalone deployments without any authentication
service the middleware falls through — the orchestration can use
/holonic/* for local experimentation without setting up OIDC.
Backing store¶
SwarmHolonicStore (indentiagraph-server/src/holonic_store.rs)
proxies the HolonicStore trait to the live SwarmDataset:
- Reads run through
QueryExecutor::executeinsidetokio::task::spawn_blockingso thesparevalpath does not starve the async runtime. - Writes use the standalone
DeltaTriples::applycommit path withStagingVocabulary+StagedBlankNodeAllocatorso concurrent updates cannot allocate overlapping LocalVocab IDs. - Turtle with
@prefixis parsed byoxttl::TurtleParserfirst and emitted as N-Triples insideINSERT DATA { GRAPH … }— SPARQL UPDATE rejects@prefixinside DATA blocks, so the defaultHolonicStore::parse_intocannot be reused. - An
update_mutexserialises writes; holding the mutex across thespawn_blockingboundary is required because the blocking task may start before the async lock is dropped.
Example — declare a holon and inject a membrane¶
# 1. Declare
curl -X POST "http://localhost:7001/holonic/holons?tenant=acme" \
-H 'Content-Type: application/json' \
-d '{"iri":"https://id.indentia.ai/identity/person/acme/leon",
"label":"Leon de Vries"}'
# 2. Interior facts
curl -X POST \
"http://localhost:7001/holonic/holons/https%3A%2F%2Fid.indentia.ai%2Fidentity%2Fperson%2Facme%2Fleon/interior?tenant=acme" \
-H 'Content-Type: application/json' \
-d '{"turtle":"<https://id.indentia.ai/identity/person/acme/leon>
<http://indentia.ai/core#hasRole>
\"Platform Architect\" ."}'
# 3. Boundary (SHACL shape as membrane)
curl -X POST \
"http://localhost:7001/holonic/holons/https%3A%2F%2Fid.indentia.ai%2Fidentity%2Fperson%2Facme%2Fleon/boundary?tenant=acme" \
-H 'Content-Type: application/json' \
-d '{"turtle":"@prefix sh: <http://www.w3.org/ns/shacl#> .
<urn:shape:Person> a sh:NodeShape ;
sh:targetClass <http://indentia.ai/core#Person> ."}'
# 4. Check readiness
curl -s http://localhost:7001/holonic/health
# → {"available": true, "default_tenant": "acme"}
Python client¶
pip install holonic[indentiagraph] — the upstream Python
package speaks the same protocol. Typical usage:
from holonic import IndentiaGraphBackend, HolonicDataset
backend = IndentiaGraphBackend(
base_url="http://localhost:7001",
tenant="acme",
)
ds = HolonicDataset(backend)
ds.add_holon("https://id.indentia.ai/identity/person/acme/leon",
label="Leon de Vries")
RAG integration¶
The Enterprise Search orchestration uses /holonic/* from a
decision-tree lane (holonic_lane) that is selected when the
intent detector classifies a query as entity_360,
multi_source, provenance, conflict, or federation. The
lane:
- Resolves the entity IRI via BB25 on the candidate graph.
- Fetches interior + boundary layers for up to
HOLONIC_MAX_HOLONS_PER_QUERYcandidates in parallel. - Runs
validate_membraneper candidate — results with a broken boundary are demoted or blocked based onHOLONIC_MEMBRANE_GATE.
Full integration rationale lives in
loom/total_picture.md §5.1 and the audit trail at
loom/HOLONIC_RAG_AUDIT_TRAIL.md.
Caveats¶
- Standalone mode only until the Raft write-path is wired through. The startup guard fails loudly when a cluster manager is attached.
- Shape graph must exist for
OutputPolicyGuardto function — the companion orchestration service ships abootstrap_shacl_shapes.pyscript that loadsOutputAnswerShapeintosources/_/ontology/output_answer_shapesbefore the first measurement run. - SPARQL
INSERT DATAcannot carry@prefixinside the data block. The customparse_intooverride is the only reason@prefix-style bootstrapping works.
See also¶
- Graph Algorithms — 35 algorithms over the LPG projection, usable on holon-derived subgraphs
- SHACL — validator used by the boundary layer
- Bitemporal — the time dimension that composes with holonic context graphs
- Enterprise Search — RAG orchestration
that consumes
/holonic/*