Ontology

One typed object model across the desk, SAP and Salesforce: object types from system metadata, objects, scored links, bound actions, lineage and agent tools.

After reading this page you will be able to:
  • Build object types from SAP or Salesforce metadata
  • Link a ticket to the records it names, with confidence and evidence
  • Bind tools to a type as its actions
  • Read lineage for syncs and tool calls
  • Let agents describe, read and follow objects

The ontology joins the systems an agent works in into one object model. A ticket can be linked to the SAP equipment it names, and that equipment to the customer's Salesforce account. Agents then ask "what is this, what is it related to, and what can be done to it" instead of reading each system's raw API.

Open Connect › Ontology (/ontology). It has tabs for Types, Objects, Links and Lineage.

Object types

A type is named <system>:<Type>, for example liya:Ticket, sap-s4hana-cloud:A_Equipment or salesforce:Account. Each type has typed properties, keys, relations to other types, a source system and a record of where it was built from.

Property kinds: string, text, integer, number, boolean, date, datetime, id, reference, picklist, email and list.

Choose Build types (POST /api/ontology/build) and pick a source:

kindBuilds from
salesforceThe org models read on the Salesforce setup page. Every reference field becomes a relation
sapThe SAP products your SAP servers connect to, narrowed to the APIs each server enables (or one product's whole catalogue)
edmxA pasted OData $metadata document, for the system you name

liya:Ticket and liya:Source are built in.

  • Custom types. Choose Add type for a system that ships no metadata. A build never overwrites a custom type.
  • Overlays. On a generated type you can change only the label, description and relations. The change is kept as an overlay that a rebuild preserves.
  • Relations. Open a type to add one, for example on A_Equipment add account to salesforce:Account where Customer equals AccountNumber.
Note

SAP metadata does not give a navigation's target type, so SAP navigations are kept as relations with no target until you name one. Cross-system relations such as equipment to account are declared by hand; they are not suggested.

Objects

An object is keyed by its origin: system, type and id. It holds bounded properties and the identifying values the resolver matches on. Tickets and sources are not copied: they are read from where they live.

Objects come from reads of bound tools (with lineage on), from the API, and from the resolver's inputs. There is no scheduled crawl that copies SAP or Salesforce records in, so a ticket only links to records something has already read.

A link is a typed relation between two objects, with a confidence and the evidence for it. Resolve links on the Links tab (POST /api/ontology/resolve) resolves one ticket, or the newest tickets as a job. Pipeline syncs also resolve the tickets they open.

EvidenceConfidence
A type's declared relation: a property equals the target's key or named match property0.95
An identifier in the ticket text with its type named beside it0.9
The requester's email address on a record0.85
An identity the identity map says the requester holds0.8
An identifier alone0.75
Another identifying property, such as a serial number0.6

When the resolver finds a link again, the higher confidence and its evidence are kept. A link you add by hand has confidence 1 and stays manual.

Actions

An action binds an MCP tool to a type and says how each argument is filled from an object: an SAP write, a Salesforce Flow, or any server's tool. Open a type to see suggested actions and choose Bind or Unbind. Suggestions come from each connection: an SAP type's get, update, delete and bound actions, and a Salesforce type's get_record and update_record.

Whether an action reads or writes comes from the server's own classification, never from the person binding it. The ontology never calls a tool. The agent calls it through its own server, so writes still go through approvals and SAP confirmations.

Lineage

TICKETIQ_ONTOLOGY_LINEAGE (default true) records who read or wrote which object, when, and whether through a sync or a tool call:

  • A call of a bound tool is lineage for the object its key arguments name, with outcome ok, error or pending (with the approval id). When a read returns JSON, each record in it is observed as an object.
  • Each source sync records that the source was read. A pipeline sync records each ticket it opened and resolves its links.
  • A stream consumer records what it read once per quality window.

Lineage is kept TICKETIQ_ONTOLOGY_LINEAGE_DAYS (default 90), never less than the retention floor. A row a legal hold covers is kept; under the audit legal hold, or when holds cannot be read, nothing is pruned.

Edits to tickets by people or by ticket tools, and knowledge article writes, are not recorded as lineage.

Agent tools

With TICKETIQ_ONTOLOGY_AGENT_TOOLS (default true), managed agents are offered three tools:

ToolDoes
ontology_describeDescribes a type: properties, relations, actions
ontology_getReads one object, with its links and its actions with arguments filled
ontology_relatedFollows links from an object
  • Cedar decides each call on Tool::"ticketiq.ontology/<op>" (describe, get or related), and checks again at call time. On a run as the invoker, the person's ontology.read and Cedar apply too.
  • Reads are scoped to the agent's tenant. Each call is audited as agent.ontology.call with the tool and type, never the result.
  • An action listed to the agent says whether the agent has that server attached.
  • A ticket comes back as its id and links only. Its title, description and requester are read with the ticket tools, under their own tenant fence, Cedar and data policies.

The tools are offered to every managed agent; there is no per-agent opt-in. Narrow them with a Cedar forbid:

forbid(principal == TicketIQ::Agent::"helper", action == TicketIQ::Action::"call_tool",
       resource == TicketIQ::Tool::"ticketiq.ontology/get");

The governed /mcp server does not expose these tools, so external MCP clients cannot reach them.

Routes and permissions

ontology.read is implied by sources.read; ontology.write by sources.write. A custom role can hold either alone.

TaskEndpointPermission
What is on, and how much the model holdsGET /api/ontology/statusontology.read
List types, read one with bound and suggested actionsGET /api/ontology/types, /types/{name}ontology.read
Add, edit or delete a typePOST /api/ontology/types, PUT or DELETE /types/{name}ontology.write
Build typesPOST /api/ontology/buildontology.write
List objects, read one with links, lineage and filled actionsGET /api/ontology/objects, /objects/{type}/{id}ontology.read
Record or forget an objectPOST /api/ontology/objects, DELETE /objects/{type}/{id}ontology.write
List, add or delete linksGET, POST /api/ontology/links, DELETE /links/{id}ontology.read / ontology.write
Related objectsGET /api/ontology/related?type=&id=&depth=ontology.read
Resolve linksPOST /api/ontology/resolveontology.write
Bind or unbind an actionPOST /api/ontology/types/{name}/actions, DELETE .../actions/{server}/{tool}ontology.write
LineageGET /api/ontology/lineageontology.read

Reading a ticket's fields at /api/ontology/objects/liya:Ticket/{id} also needs tickets.read. Every write is made in the caller's own tenant and audited as ontology.*. On an instance with tenants, an account with no tenant is refused a write.

Warning

Objects observed from a bound read are stored in the caller's tenant, shaped by the data policies of whoever made that call. Anyone in the tenant with ontology.read can then read them. There is no per-object access control yet.

Deletion and erasure

  • Forgetting an object removes it and its links. Its lineage stays: what happened to it still happened.
  • A source deletion removes the deleted records' objects and their links, and keeps their lineage. See Deletion propagation.
  • A deleted ticket loses its object row, its links and its lineage, in every tenant.
  • A GDPR erasure finds objects, links and lineage that name the person. Their own objects, and any whose id names them, are deleted with their links and lineage: these are copies, and the source system keeps the original. An object that only mentions them is kept with every mention replaced. A link naming them is deleted, so it cannot tie a pseudonymised ticket back to them. A lineage row is redacted, or deleted with its object. See GDPR.
  • A deleted tenant loses its types and bound actions, and its objects, links and lineage unless a hold on the tenant or the audit legal hold keeps them.