Skip to content

[FEATURE]: Support actions in ontologies #43

@larsgeorge-db

Description

@larsgeorge-db

Is there an existing issue for this?

  • I have searched the existing issues

Problem statement

We want to support actions that are based on declarative business-level conditions, often modelled in existing ontologies. Right now the Compliance feature reports retrospectively based on observation and applying checks implemented in various ways (DSL, SQL, SPARQL, ...). It would make sense to trigger actions based on those.

Proposed Solution

This issue proposes a pattern for representing Actions in the ontology of a data‑product platform, so that business‑level conditions over terms/metrics can be turned into executable operations (e.g., recomputations, notifications, or downstream API calls). The idea is to keep action semantics declarative in the knowledge graph and let an external “action engine” interpret and execute them.

Concept

  • Actions are first‑class resources in the ontology, not just ad‑hoc code paths.
  • Each Action:
    • Has a Condition (a graph‑level pattern or metric predicate).
    • Has one or more Effect nodes describing concrete side‑effects (e.g., HTTP call).
    • Is linked to the data products and business terms it concerns.
  • The action engine:
    • Evaluates Condition patterns (e.g., SPARQL, SHACL rules) against the graph.
    • For each match, instantiates and executes the associated Effect (e.g., POST to an endpoint with a templated payload).

This keeps the “why” (semantics and justification) in the graph, and the “how” (execution) in a separate, replaceable component.


Example Turtle

The example below shows:

  • Core classes: Action, Condition, Effect, DataProduct, Metric, BusinessTerm.
  • A condition describing “high churn risk customer”.
  • An effect that calls a CRM endpoint.
  • An action that ties them together, scoped to a Customer360 data product.
@prefix :      <https://example.com/onto/> .
@prefix dp:    <https://example.com/dataproduct/> .
@prefix act:   <https://example.com/action/> .
@prefix term:  <https://example.com/term/> .
@prefix metric:<https://example.com/metric/> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .

#############
# Core types
#############

act:Action a rdfs:Class ;
  rdfs:label "Action" ;
  rdfs:comment "An executable, parameterised operation that can be triggered by graph-level conditions." .

act:Condition a rdfs:Class ;
  rdfs:label "Condition" ;
  rdfs:comment "A declarative description of when an action is applicable." .

act:Effect a rdfs:Class ;
  rdfs:label "Effect" ;
  rdfs:comment "A side-effect or outcome produced when an action is executed." .

dp:DataProduct a rdfs:Class ;
  rdfs:label "Data product" .

metric:Metric a rdfs:Class ;
  rdfs:label "Metric" .

term:BusinessTerm a rdfs:Class ;
  rdfs:label "Business term" .

#####################
# Action vocabulary
#####################

act:RecomputeDataProduct a rdfs:Class ;
  rdfs:subClassOf act:Action ;
  rdfs:label "Recompute data product" .

act:NotifyOwner a rdfs:Class ;
  rdfs:subClassOf act:Action ;
  rdfs:label "Notify owner" .

##############
# Properties
##############

act:hasCondition a rdf:Property ;
  rdfs:domain act:Action ;
  rdfs:range  act:Condition ;
  rdfs:label "has condition" .

act:hasEffect a rdf:Property ;
  rdfs:domain act:Action ;
  rdfs:range  act:Effect ;
  rdfs:label "has effect" .

act:actsOnProduct a rdf:Property ;
  rdfs:domain act:Action ;
  rdfs:range  dp:DataProduct ;
  rdfs:label "acts on data product" .

act:aboutTerm a rdf:Property ;
  rdfs:domain act:Action ;
  rdfs:range  term:BusinessTerm ;
  rdfs:label "about business term" .

act:usesMetric a rdf:Property ;
  rdfs:domain act:Condition ;
  rdfs:range  metric:Metric ;
  rdfs:label "uses metric" .

act:threshold a rdf:Property ;
  rdfs:domain act:Condition ;
  rdfs:range  xsd:decimal ;
  rdfs:label "threshold" .

act:operator a rdf:Property ;
  rdfs:domain act:Condition ;
  rdfs:range  xsd:string ;
  rdfs:label "operator" ;
  rdfs:comment "For simplicity, a textual operator like '<', '>', '<=', '>='." .

act:sparqlPattern a rdf:Property ;
  rdfs:domain act:Condition ;
  rdfs:range  xsd:string ;
  rdfs:label "SPARQL pattern" ;
  rdfs:comment "Serialized SPARQL or graph pattern evaluated by an external engine." .

act:httpEndpoint a rdf:Property ;
  rdfs:domain act:Effect ;
  rdfs:range  xsd:anyURI ;
  rdfs:label "HTTP endpoint" .

act:method a rdf:Property ;
  rdfs:domain act:Effect ;
  rdfs:range  xsd:string ;
  rdfs:label "HTTP method" .

act:payloadTemplate a rdf:Property ;
  rdfs:domain act:Effect ;
  rdfs:range  xsd:string ;
  rdfs:label "Payload template" ;
  rdfs:comment "A template (e.g. JSON with placeholders) filled by the action engine." .

#######################
# Domain instances
#######################

dp:Customer360 a dp:DataProduct ;
  rdfs:label "Customer 360 data product" .

metric:CustomerChurnRiskScore a metric:Metric ;
  rdfs:label "Customer churn risk score" .

term:HighChurnRiskCustomer a term:BusinessTerm ;
  rdfs:label "High churn risk customer" .

###########################################
# A condition: churn risk above threshold
###########################################

act:HighChurnRiskCondition a act:Condition ;
  rdfs:label "High churn risk condition" ;
  act:usesMetric metric:CustomerChurnRiskScore ;
  act:threshold "0.8"^^xsd:decimal ;
  act:operator ">" ;
  act:sparqlPattern """
    PREFIX metric: <https://example.com/metric/>
    PREFIX term:   <https://example.com/term/>
    PREFIX ex:     <https://example.com/domain/>

    CONSTRUCT {
      ?cust a term:HighChurnRiskCustomer .
    }
    WHERE {
      ?cust metric:hasChurnRiskScore ?score .
      FILTER(?score > 0.8)
    }
  """ .

###############################################
# Effect: call downstream system / workflow
###############################################

act:CreateOutreachTaskEffect a act:Effect ;
  rdfs:label "Create outreach task in CRM" ;
  act:httpEndpoint <https://crm.example.com/api/tasks> ;
  act:method "POST" ;
  act:payloadTemplate """
    {
      "type": "OUTREACH",
      "customerId": "{{custId}}",
      "reason": "High churn risk",
      "source": "ontology-action-engine",
      "dataProduct": "Customer360"
    }
  """ .

##########################################################
# Action tying condition, product, term, and effect
##########################################################

act:CreateOutreachTaskForHighChurnCustomers
  a act:RecomputeDataProduct , act:NotifyOwner ;
  rdfs:label "Create outreach tasks for high churn customers" ;
  act:actsOnProduct dp:Customer360 ;
  act:aboutTerm term:HighChurnRiskCustomer ;
  act:hasCondition act:HighChurnRiskCondition ;
  act:hasEffect act:CreateOutreachTaskEffect .

Discussion points

  • Do we want to standardize on SPARQL strings for conditions, or use SHACL rules for better validation and tooling support?
  • How should the action engine bind variables (e.g., ?cust) into the payloadTemplate (Jinja‑style, JSON‑LD framing, etc.)?
  • Should Actions and Effects be versioned alongside data products, so that behavior changes are tracked in the same governance flow?

If this approach looks reasonable, the next steps could be:

  1. Introduce these classes and properties into the core ontology module.
  2. Implement a small action executor that:
    • Reads act:Action instances.
    • Evaluates act:Condition patterns.
    • Calls act:Effect endpoints with rendered payloads.
  3. Add tests showing that changes in the graph (e.g., churn scores) lead to the expected external calls.

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfeat/complianceCompliance check related featurefeatureFeature requests

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions