Ontology Federation & Package Migration¶
Domain ontologies live in the agent-package that owns their domain, not in the agent-utilities wheel — federated back into the canonical ontology by IRI. Concepts:
AU-KG.ontology(loader/discovery) andAU-KG.ontology.package-federation-migration(the ~14-package migration). Catalog of what lives where:ontology_library.md.
The idea¶
The knowledge graph is one ontology library: a canonical upper ontology
(knowledge_graph/ontology.ttl, IRI http://knuckles.team/kg) that owl:imports a domain
module per vertical. Those domain modules do not all have to ship inside agent-utilities.
Any fleet package can contribute its own owl:Ontology module — the same "third federation leg"
pattern used for skills and prompts — so, e.g., the ServiceNow ontology lives in
servicenow-api, the LeanIX ontology in leanix-agent, and the finance ontologies in
emerald-exchange. The canonical file keeps its owl:imports edge unchanged; when the owning
package is installed its .ttl is discovered and folded in, and when it is absent the import is
a tolerated superset no-op.
flowchart TD
Canon["ontology.ttl (canonical upper)\nIRI http://knuckles.team/kg\nowl:imports every domain IRI"]
subgraph Core["Stays in agent-utilities (core/upper)"]
C1["action · capability · enterprise · company · orchestration\nidentity · infrastructure · harness · sdd · software · system · a2a …"]
end
subgraph Pkgs["Federated — owned by agent-packages/*"]
P1["servicenow-api → servicenow.ttl"]
P2["leanix-agent → leanix.ttl"]
P3["emerald-exchange → quant/trading/banking.ttl"]
P4["lgtm-mcp → grafana/observability.ttl … (12 packages)"]
end
Canon --> Core
Canon -.owl:imports (federated IRI).-> Pkgs
Pkgs -->|agent_utilities.ontology_providers ep| Loader["ontology_federation.py\ndiscover/resolve_provider_ontologies()"]
Loader --> Glob["3 load points:\nontology_publisher · owlready2_backend · check_ontology.py"]
Reg["REGISTERED_FEDERATED_IRIS"] -.->|import resolves even when pkg absent| Canon
Mechanism¶
-
The entry-point. Each owning package declares, in its
and shipspyproject.toml:"ontology/**"in its package-data. The<module>/ontology/directory holds the.ttlfile(s) (one package may carry several, e.g.emerald_exchange/ontology/hasquant.ttl,trading.ttl,banking.ttl) plus a data-only__init__.py. -
Discovery.
knowledge_graph/core/ontology_federation.pyresolves everyagent_utilities.ontology_providersentry-point to its data dir viaiter_provider_dirs(the same resolver skills/prompts use) and flattens to each concrete*.ttl(+shapes/*.ttl): discover_provider_ontologies()— live entry-point discovery.-
resolve_provider_ontologies()— XDG-first (the unified tree written byagent-utilities install), falling back to live discovery. -
The three load points all consume that discovery so a federated module behaves exactly like a bundled one:
core/ontology_publisher.collect_bundled_ontology_graph()— Stardog/Fuseki publish.backends/owl/owlready2_backend._register_local_imports()— pre-parse for the live reasoner.-
scripts/check_ontology.py— the valid/connected/SHACL gate. -
REGISTERED_FEDERATED_IRIS(inontology_federation.py) is the ledger of IRIs the canonical bundle mayowl:importseven when the owning package is not installed. Without it,check_ontologywould flag the import as dangling in a provider-less base install. Every migrated domain has one entry here. -
Runtime.
graph_ontology action=sync_packages(MCP + REST) drivesOntologyLifecycle.loadover the discovered providers; uninstalling a package removes its contribution for free viaentry_points().
What has been migrated¶
15 domain ontologies moved out of the wheel into 12 owning packages (concept
AU-KG.ontology.package-federation-migration):
| Domain(s) | Owning package |
|---|---|
| servicenow | servicenow-api (original pilot) |
| leanix | leanix-agent |
| erpnext | erpnext-agent |
| archimate | archimate-mcp |
| egeria | egeria-mcp |
| quant, trading, banking | emerald-exchange |
| legal | legal-peripherals-mcp |
| media | jellyfin-mcp |
| grafana, observability | lgtm-mcp |
| social | postiz-agent |
| feed | freshrss-agent |
| wellness | wger-agent |
| database | sql-mcp |
Stays in core (import root / shared vocab — moving would break OWL-RL closure):
ontology.ttl, action, capability, enterprise, company, company_infra,
orchestration, sdd, software, system, a2a, harness, identity, infrastructure.
Homeless (kept in core until an owner is named): calendar, personal, hr, medical,
government, energy_geopolitics, trm.
Note:
ontology_company.ttl(core)owl:importsthebankingandlegalIRIs, so both are registered inREGISTERED_FEDERATED_IRIS— a core module importing a now-federated IRI is fine, exactly what the registry is for.
Migrating a new domain (the recipe)¶
- Pre-flight — check for shared vocab.
grepthe domain IRI across all.ttlfiles. If anything other than the canonicalontology.ttlimports it, that importer is shared vocab: either keep the module in core, or migrate it and ensure the importer resolves viaREGISTERED_FEDERATED_IRIS(as done for banking/legal). - Create the package module:
<pkg>/<module>/ontology/<x>.ttl(IRIhttp://knuckles.team/kg/<x>unchanged) + a data-onlyontology/__init__.py. - Wire pyproject: add the
agent_utilities.ontology_providersentry-point (key =[project].name) and"ontology/**"to package-data. - Register the IRI: add it to
REGISTERED_FEDERATED_IRISinontology_federation.py. - Delete from core: remove
knowledge_graph/ontology_<x>.ttl; move its row from the "Domain modules" table to the "Federated" table inontology_library.md. - Keep the canonical import edge (
ontology.ttlstillowl:imports http://knuckles.team/kg/<x>). - Make it atomic — add-to-package + register-IRI + delete-from-core in one change — so
check_ontology.pystays green throughout (the federation loader makes provider ttls a superset; a file deleted from core but not yet registered fails the gate).
Verify¶
# with the package NOT installed — canonical imports still resolve via REGISTERED_FEDERATED_IRIS
python scripts/check_ontology.py -v # OK — N ontologies valid, connected, documented
# with the package installed
graph_ontology action=sync_packages # loads provider ttls
graph_ontology action=list # the migrated IRI now appears
Both the pilot (servicenow) and this 15-domain batch keep check_ontology -v green with and
without the owning packages installed.