-
Notifications
You must be signed in to change notification settings - Fork 21
Description
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
Effectnodes describing concrete side‑effects (e.g., HTTP call). - Is linked to the data products and business terms it concerns.
- Has a
- The action engine:
- Evaluates
Conditionpatterns (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).
- Evaluates
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
Customer360data 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 thepayloadTemplate(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:
- Introduce these classes and properties into the core ontology module.
- Implement a small action executor that:
- Reads
act:Actioninstances. - Evaluates
act:Conditionpatterns. - Calls
act:Effectendpoints with rendered payloads.
- Reads
- Add tests showing that changes in the graph (e.g., churn scores) lead to the expected external calls.
Additional Context
No response