diff --git a/rocrate_validator/profiles/five-safes-crate/may/11_workflow_execution_phase.ttl b/rocrate_validator/profiles/five-safes-crate/may/11_workflow_execution_phase.ttl index 6c331913..8d3175d5 100644 --- a/rocrate_validator/profiles/five-safes-crate/may/11_workflow_execution_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/may/11_workflow_execution_phase.ttl @@ -22,6 +22,35 @@ @prefix xsd: . +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + + five-safes-crate:WorkflowexecutionObjectHasStartTimeIfBegun a sh:NodeShape ; sh:name "WorkflowExecution" ; @@ -34,11 +63,11 @@ five-safes-crate:WorkflowexecutionObjectHasStartTimeIfBegun a sh:SPARQLTarget ; sh:select """ PREFIX schema: - PREFIX rdf: + PREFIX rocrate: SELECT ?this WHERE { - ?this rdf:type schema:CreateAction ; + ?this a rocrate:WorkflowRun ; schema:actionStatus ?status . FILTER(?status IN ( "http://schema.org/CompletedActionStatus", diff --git a/rocrate_validator/profiles/five-safes-crate/may/1_responsible_project.ttl b/rocrate_validator/profiles/five-safes-crate/may/1_responsible_project.ttl index 5dd46fd2..eabcc39b 100644 --- a/rocrate_validator/profiles/five-safes-crate/may/1_responsible_project.ttl +++ b/rocrate_validator/profiles/five-safes-crate/may/1_responsible_project.ttl @@ -22,6 +22,35 @@ @prefix xsd: . +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + + five-safes-crate:ResponsibleProject a sh:NodeShape ; sh:name "Responsible Project" ; @@ -30,7 +59,7 @@ five-safes-crate:ResponsibleProject sh:prefixes ro-crate:sparqlPrefixes ; sh:select """ SELECT DISTINCT ?this WHERE { - ?action a schema:CreateAction ; + ?action a ro-crate:WorkflowRun ; schema:agent ?agent . ?agent schema:memberOf ?this . } @@ -53,4 +82,4 @@ five-safes-crate:ResponsibleProject sh:minCount 1 ; sh:severity sh:Info ; sh:message """The Responsible Project does not have the property `member`.""" ; - ] . \ No newline at end of file + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/must/11_workflow_execution_phase.ttl b/rocrate_validator/profiles/five-safes-crate/must/11_workflow_execution_phase.ttl index d036e9bb..7bb3804b 100644 --- a/rocrate_validator/profiles/five-safes-crate/must/11_workflow_execution_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/must/11_workflow_execution_phase.ttl @@ -23,33 +23,62 @@ @prefix xsd: . +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + + five-safes-crate:WorkflowMustHaveDescriptiveName a sh:NodeShape ; sh:name "WorkflowExecution" ; - sh:targetClass schema:CreateAction ; + sh:targetClass ro-crate:WorkflowRun ; sh:property [ a sh:PropertyShape ; sh:name "name" ; sh:minCount 1 ; - sh:description "Workflow (CreateAction) MUST have a name string of at least 10 characters." ; + sh:description "WorkflowRun MUST have a name string of at least 10 characters." ; sh:path schema:name ; sh:datatype xsd:string ; sh:minLength 10 ; sh:severity sh:Violation ; - sh:message "Workflow (CreateAction) MUST have a name string of at least 10 characters." ; + sh:message "WorkflowRun MUST have a name string of at least 10 characters." ; ] . five-safes-crate:WorkflowMustHaveActionStatusWithAllowedValues a sh:NodeShape ; sh:name "WorkflowExecution" ; - sh:targetClass schema:CreateAction ; + sh:targetClass ro-crate:WorkflowRun ; sh:property [ a sh:PropertyShape ; sh:minCount 1 ; sh:name "actionStatus" ; - sh:description "WorkflowExecution MUST have an actionStatus with an allowed value (see https://schema.org/ActionStatusType)." ; + sh:description "WorkflowRun MUST have an actionStatus with an allowed value (see https://schema.org/ActionStatusType)." ; sh:path schema:actionStatus ; sh:in ( "http://schema.org/PotentialActionStatus" @@ -58,5 +87,5 @@ five-safes-crate:WorkflowMustHaveActionStatusWithAllowedValues "http://schema.org/FailedActionStatus" ) ; sh:severity sh:Violation ; - sh:message "WorkflowExecution MUST have an actionStatus with an allowed value (see https://schema.org/ActionStatusType)." ; + sh:message "WorkflowRun MUST have an actionStatus with an allowed value (see https://schema.org/ActionStatusType)." ; ] . diff --git a/rocrate_validator/profiles/five-safes-crate/must/7_requested_workflow_run.ttl b/rocrate_validator/profiles/five-safes-crate/must/7_requested_workflow_run.ttl index 5f513532..3a3ede79 100644 --- a/rocrate_validator/profiles/five-safes-crate/must/7_requested_workflow_run.ttl +++ b/rocrate_validator/profiles/five-safes-crate/must/7_requested_workflow_run.ttl @@ -22,7 +22,37 @@ @prefix xsd: . -five-safes-crate:RootDataEntityMentionsCreateAction +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + # Expand data graph with triples from the file data entity + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + + +five-safes-crate:RootDataEntityMentionsWorkflowRun a sh:NodeShape ; sh:name "RootDataEntity" ; sh:targetClass ro-crate:RootDataEntity ; @@ -33,42 +63,43 @@ five-safes-crate:RootDataEntityMentionsCreateAction sh:name "mentions" ; sh:path schema:mentions; sh:qualifiedValueShape [ - sh:class schema:CreateAction ; + sh:class ro-crate:WorkflowRun ; ] ; sh:qualifiedMinCount 1 ; sh:severity sh:Violation ; - sh:message "`RootDataEntity` MUST reference at least one `CreateAction` through `mentions`" ; + sh:message "`RootDataEntity` MUST reference at least one `WorkflowRun` through `mentions`" ; ] . -five-safes-crate:CreateActionInstrumentAndStatus +five-safes-crate:WorkflowRunExistence a sh:NodeShape ; - sh:name "CreateAction" ; - sh:targetClass schema:CreateAction ; - sh:description "" ; - sh:severity sh:Violation ; # Apply to all property shapes / constraints below + sh:name "RootDataEntity" ; + sh:targetClass ro-crate:RootDataEntity ; + sh:description "" ; - sh:property [ - a sh:PropertyShape ; - sh:name "instrument" ; - sh:path schema:instrument; - sh:minCount 1 ; - sh:message "`CreateAction` MUST have the `instrument` property" ; - ] ; sh:sparql [ a sh:SPARQLConstraint ; - sh:name "instrument" ; + sh:name "WorkflowRun" ; sh:prefixes ro-crate:sparqlPrefixes ; sh:select """ - SELECT $this ?main ?instrument - WHERE { - ?root schema:mainEntity ?main . - $this schema:instrument ?instrument . - FILTER (?instrument != ?main) - } + SELECT $this + WHERE { + FILTER NOT EXISTS { + ?workflowRun a ro-crate:WorkflowRun . + } + } """ ; - sh:message "`CreateAction` --> `instrument` MUST reference the same entity as `Root Data Entity` --> `mainEntity`" ; - ] ; + sh:message "The crate MUST contain at least one `WorkflowRun` entity" ; + ] . + + +five-safes-crate:WorkflowRunObject + a sh:NodeShape ; + sh:name "WorkflowRun" ; + sh:targetClass ro-crate:WorkflowRun ; + sh:description "" ; + sh:severity sh:Violation ; # Apply to all property shapes / constraints below + sh:sparql [ a sh:SPARQLConstraint ; sh:prefixes ro-crate:sparqlPrefixes ; @@ -80,5 +111,5 @@ five-safes-crate:CreateActionInstrumentAndStatus FILTER NOT EXISTS { ?object a ?type . } } """ ; - sh:message "Each `object` in `CreateAction` MUST reference an existing entity." ; - ] . \ No newline at end of file + sh:message "Each `object` in `WorkflowRun` MUST reference an existing entity." ; + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/ontology.ttl b/rocrate_validator/profiles/five-safes-crate/ontology.ttl new file mode 100644 index 00000000..987fd1f9 --- /dev/null +++ b/rocrate_validator/profiles/five-safes-crate/ontology.ttl @@ -0,0 +1,37 @@ +# Copyright (c) 2024-2026 CRS4 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +@prefix ro: <./> . +@prefix owl: . +@prefix rdf: . +@prefix xml: . +@prefix xsd: . +@prefix rdfs: . +@prefix schema: . +@prefix rocrate: . +@prefix bioschemas: . +@prefix ro-crate: . +@prefix isa-ro-crate: . + + rdf:type owl:Ontology ; + owl:versionIRI . + +# # ################################################################# +# # # Classes +# # ################################################################# + +# Declare a WorkflowRun class +ro-crate:WorkflowRun rdf:type owl:Class ; + rdfs:subClassOf schema:CreateAction ; + rdfs:label "WorkflowRun"@en . diff --git a/rocrate_validator/profiles/five-safes-crate/should/10_outputs.ttl b/rocrate_validator/profiles/five-safes-crate/should/10_outputs.ttl index f3d56ed5..2761bd4b 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/10_outputs.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/10_outputs.ttl @@ -22,20 +22,49 @@ @prefix xsd: . +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + -five-safes-crate:CreateActionHasResultIfActionCompleted + +five-safes-crate:WorkflowRunHasResultIfActionCompleted a sh:NodeShape ; - sh:name "CreateAction" ; - sh:description "`CreateAction` with CompletedActionStatus SHOULD have the `schema:result` property." ; + sh:name "WorkflowRun" ; + sh:description "`WorkflowRun` with CompletedActionStatus SHOULD have the `schema:result` property." ; sh:target [ a sh:SPARQLTarget ; - sh:name "Result" ; - sh:description "`CreateAction` with CompletedActionStatus SHOULD have the `schema:result` property." ; + sh:name "WorkflowRun" ; + sh:description "`WorkflowRun` with CompletedActionStatus SHOULD have the `result` property." ; sh:prefixes ro-crate:sparqlPrefixes ; sh:select """ SELECT ?this WHERE { - ?this a schema:CreateAction ; + ?this a ro-crate:WorkflowRun ; schema:actionStatus "http://schema.org/CompletedActionStatus" . } """ @@ -48,22 +77,22 @@ five-safes-crate:CreateActionHasResultIfActionCompleted sh:path schema:result ; sh:minCount 1 ; sh:severity sh:Warning ; - sh:message "`CreateAction` with CompletedActionStatus SHOULD have the `result` property." ; + sh:message "`WorkflowRun` with CompletedActionStatus SHOULD have the `result` property." ; ] . -five-safes-crate:CreateActionResultOutputsHaveAllowedTypes +five-safes-crate:WorkflowRunResultOutputsHaveAllowedTypes a sh:NodeShape ; sh:name "Output" ; sh:description "Result SHOULD have a `@type` among an allowed set of values." ; sh:target [ a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; sh:select """ - PREFIX schema: SELECT ?this WHERE { - ?createAction a schema:CreateAction . - ?createAction schema:result ?this . + ?workflowRun a ro-crate:WorkflowRun . + ?workflowRun schema:result ?this . } """ ; ] ; @@ -86,4 +115,3 @@ five-safes-crate:CreateActionResultOutputsHaveAllowedTypes sh:class schema:PropertyValue; ] ) . - diff --git a/rocrate_validator/profiles/five-safes-crate/should/11_workflow_execution_phase.ttl b/rocrate_validator/profiles/five-safes-crate/should/11_workflow_execution_phase.ttl index 0c152310..3183e60a 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/11_workflow_execution_phase.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/11_workflow_execution_phase.ttl @@ -23,29 +23,58 @@ @prefix xsd: . +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + + five-safes-crate:RootDataEntityShouldMentionWorkflow a sh:NodeShape ; sh:name "RootDataEntity" ; - sh:description "RootDataEntity SHOULD mention workflow execution object (typed CreateAction)." ; + sh:description "RootDataEntity SHOULD mention workflow execution object (typed WorkflowRun)." ; sh:targetClass ro-crate:RootDataEntity ; sh:sparql [ a sh:SPARQLConstraint ; sh:name "mentions" ; sh:select """ PREFIX schema: - PREFIX rdf: + PREFIX rocrate: SELECT $this WHERE { FILTER NOT EXISTS { $this schema:mentions ?workflowExecution . - ?workflowExecution rdf:type schema:CreateAction . + ?workflowExecution a rocrate:WorkflowRun . } } """ ; sh:severity sh:Warning ; - sh:message "RootDataEntity SHOULD mention workflow execution object (typed CreateAction)." ; + sh:message "RootDataEntity SHOULD mention workflow execution object (typed WorkflowRun)." ; ] . @@ -59,11 +88,11 @@ five-safes-crate:WorkflowexecutionObjectHasEndTimeIfEnded a sh:SPARQLTarget ; sh:select """ PREFIX schema: - PREFIX rdf: + PREFIX rocrate: SELECT ?this WHERE { - ?this rdf:type schema:CreateAction ; + ?this a rocrate:WorkflowRun ; schema:actionStatus ?status . FILTER(?status IN ( "http://schema.org/CompletedActionStatus", @@ -82,4 +111,4 @@ five-safes-crate:WorkflowexecutionObjectHasEndTimeIfEnded sh:severity sh:Warning ; sh:description "The workflow execution object SHOULD have an endTime property if it has ended." ; sh:message "The workflow execution object SHOULD have an endTime property if it has ended." ; - ] . \ No newline at end of file + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/should/1_requesting_agent.ttl b/rocrate_validator/profiles/five-safes-crate/should/1_requesting_agent.ttl index 332c67d3..1117d96d 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/1_requesting_agent.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/1_requesting_agent.ttl @@ -22,6 +22,35 @@ @prefix xsd: . +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + + five-safes-crate:AgentIsMemberOf a sh:NodeShape ; sh:name "Requesting Agent" ; @@ -30,7 +59,7 @@ five-safes-crate:AgentIsMemberOf sh:prefixes ro-crate:sparqlPrefixes ; sh:select """ SELECT DISTINCT ?this WHERE { - ?action a schema:CreateAction ; + ?action a rocrate:WorkflowRun ; schema:agent ?this . } """ @@ -43,4 +72,4 @@ five-safes-crate:AgentIsMemberOf sh:minCount 1 ; sh:severity sh:Warning ; sh:message """The Requesting Agent SHOULD have a `memberOf` property.""" ; - ] . \ No newline at end of file + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/should/1_responsible_project.ttl b/rocrate_validator/profiles/five-safes-crate/should/1_responsible_project.ttl index 2c5c4d4a..619d2e70 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/1_responsible_project.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/1_responsible_project.ttl @@ -22,6 +22,35 @@ @prefix xsd: . +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + + five-safes-crate:ResponsibleProjectMemberAndSourceOrganizationIntersection a sh:NodeShape ; sh:name "Organizations (members of Responsible Project)" ; @@ -33,7 +62,7 @@ five-safes-crate:ResponsibleProjectMemberAndSourceOrganizationIntersection sh:prefixes ro-crate:sparqlPrefixes ; sh:select """ SELECT DISTINCT ?this WHERE { - ?action a schema:CreateAction ; + ?action a ro-crate:WorkflowRun ; schema:agent ?this . ?this a schema:Person ; schema:memberOf ?project ; @@ -59,4 +88,4 @@ five-safes-crate:ResponsibleProjectMemberAndSourceOrganizationIntersection } """ ; sh:message """At least one of the organisations that are members of the responsible project SHOULD be included in the Requesting Agent's affiliations, if such properties exist.""" ; - ] . \ No newline at end of file + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/should/2_requesting_agent.ttl b/rocrate_validator/profiles/five-safes-crate/should/2_requesting_agent.ttl index c21b3f97..95924e37 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/2_requesting_agent.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/2_requesting_agent.ttl @@ -22,28 +22,57 @@ @prefix xsd: . -# Person who is the agent of a CreateAction SHOULD have an affiliation +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + + +# Person who is the agent of a WorkflowRun SHOULD have an affiliation five-safes-crate:PersonAgentHasAffiliation a sh:NodeShape ; - sh:name "Agent of CreateAction" ; - sh:description "The agent of a CreateAction entity" ; + sh:name "Agent of WorkflowRun" ; + sh:description "The agent of a WorkflowRun entity" ; sh:target [ a sh:SPARQLTarget ; sh:prefixes ro-crate:sparqlPrefixes ; sh:select """ SELECT DISTINCT ?this WHERE { - ?action a schema:CreateAction ; + ?action a ro-crate:WorkflowRun ; schema:agent ?this . } """ ] ; - # The agent of a CreateAction entity SHOULD have an affiliation + # The agent of a WorkflowRun entity SHOULD have an affiliation sh:property [ a sh:PropertyShape ; sh:name "Presence of affiliations" ; sh:path schema:affiliation ; sh:minCount 1 ; sh:severity sh:Warning ; - sh:message "The agent of a CreateAction entity SHOULD have an affiliation" ; - ] . \ No newline at end of file + sh:message "The agent of a WorkflowRun entity SHOULD have an affiliation" ; + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/should/7_requested_workflow_run.ttl b/rocrate_validator/profiles/five-safes-crate/should/7_requested_workflow_run.ttl index 41af739c..787473d5 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/7_requested_workflow_run.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/7_requested_workflow_run.ttl @@ -22,15 +22,44 @@ @prefix xsd: . -# CreateAction SHOULD have object property with minimum cardinality 1 -five-safes-crate:CreateActionShouldHaveObjectProperty +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + + +# WorkflowRun SHOULD have object property with minimum cardinality 1 +five-safes-crate:WorkflowRunShouldHaveObjectProperty a sh:NodeShape ; - sh:targetClass schema:CreateAction ; - sh:name "CreateAction" ; + sh:targetClass ro-crate:WorkflowRun ; + sh:name "WorkflowRun" ; sh:property [ sh:path schema:object ; sh:minCount 1 ; sh:nodeKind sh:IRI ; sh:severity sh:Warning ; - sh:message "`CreateAction` SHOULD have the property `object` with IRI values." ; - ] . \ No newline at end of file + sh:message "`WorkflowRun` SHOULD have the property `object` with IRI values." ; + ] . diff --git a/rocrate_validator/profiles/five-safes-crate/should/9_inputs.ttl b/rocrate_validator/profiles/five-safes-crate/should/9_inputs.ttl index 57261096..3a80c367 100644 --- a/rocrate_validator/profiles/five-safes-crate/should/9_inputs.ttl +++ b/rocrate_validator/profiles/five-safes-crate/should/9_inputs.ttl @@ -24,6 +24,35 @@ @prefix xsd: . +ro-crate:FindWorkflowRunAction a sh:NodeShape, validator:HiddenShape; + sh:name "Identify the CreateAction Entity that corresponds to the Workflow run" ; + sh:description """The Workflow Run is the CreateAction entity that refers to Workflow run. + This is identified by checking that the CreateAction entity has an `instrument` property + that references the same entity as the `mainEntity` property of the Root Data Entity.""" ; + sh:target [ + a sh:SPARQLTarget ; + sh:prefixes ro-crate:sparqlPrefixes ; + sh:select """ + SELECT ?this + WHERE { + ?this a schema:CreateAction ; + schema:instrument ?instrument . + ?root schema:mainEntity ?instrument ; + a schema:Dataset . + ?metadatafile schema:about ?root . + FILTER(contains(str(?metadatafile), "ro-crate-metadata.json")) + } + """ + ] ; + + sh:rule [ + a sh:TripleRule ; + sh:subject sh:this ; + sh:predicate rdf:type ; + sh:object ro-crate:WorkflowRun ; + ] . + + five-safes-crate:InputEntityReferencesFormalParameterViaExampleOfWork a sh:NodeShape ; @@ -34,7 +63,7 @@ five-safes-crate:InputEntityReferencesFormalParameterViaExampleOfWork sh:prefixes ro-crate:sparqlPrefixes ; sh:select """ SELECT ?this WHERE { - ?action a schema:CreateAction ; + ?action a ro-crate:WorkflowRun ; schema:object ?this . } """ @@ -55,4 +84,4 @@ five-safes-crate:InputEntityReferencesFormalParameterViaExampleOfWork """ ; sh:severity sh:Warning ; sh:message "Input SHOULD reference a FormalParameter using exampleOfWork" ; - ] . \ No newline at end of file + ] . diff --git a/rocrate_validator/profiles/ro-crate/prefixes.ttl b/rocrate_validator/profiles/ro-crate/prefixes.ttl index 79006d53..37322c74 100644 --- a/rocrate_validator/profiles/ro-crate/prefixes.ttl +++ b/rocrate_validator/profiles/ro-crate/prefixes.ttl @@ -46,4 +46,8 @@ ro-crate:sparqlPrefixes sh:declare [ sh:prefix "ro" ; sh:namespace "./"^^xsd:anyURI ; - ] . + ] ; + sh:declare [ + sh:prefix "ro-crate" ; + sh:namespace "https://github.com/crs4/rocrate-validator/profiles/ro-crate/"^^xsd:anyURI ; + ]. diff --git a/tests/integration/profiles/five-safes-crate/test_5src_10_outputs.py b/tests/integration/profiles/five-safes-crate/test_5src_10_outputs.py index c797b582..2112c52f 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_10_outputs.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_10_outputs.py @@ -50,9 +50,9 @@ def test_completed_createaction_does_not_have_result(): rocrate_path=ValidROC().five_safes_crate_result, requirement_severity=Severity.RECOMMENDED, expected_validation_result=False, - expected_triggered_requirements=["CreateAction"], + expected_triggered_requirements=["WorkflowRun"], expected_triggered_issues=[ - "`CreateAction` with CompletedActionStatus SHOULD have the `result` property." + "`WorkflowRun` with CompletedActionStatus SHOULD have the `result` property." ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, diff --git a/tests/integration/profiles/five-safes-crate/test_5src_11_workflow_execution.py b/tests/integration/profiles/five-safes-crate/test_5src_11_workflow_execution.py index 49a9a8f9..ce5448d3 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_11_workflow_execution.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_11_workflow_execution.py @@ -47,7 +47,7 @@ def test_5src_workflow_object_with_no_name(): expected_validation_result=False, expected_triggered_requirements=["WorkflowExecution"], expected_triggered_issues=[ - "Workflow (CreateAction) MUST have a name string of at least 10 characters." + "WorkflowRun MUST have a name string of at least 10 characters." ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, @@ -78,7 +78,7 @@ def test_5src_workflow_object_with_name_not_string(): expected_validation_result=False, expected_triggered_requirements=["WorkflowExecution"], expected_triggered_issues=[ - "Workflow (CreateAction) MUST have a name string of at least 10 characters." + "WorkflowRun MUST have a name string of at least 10 characters." ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, @@ -109,7 +109,7 @@ def test_5src_workflow_object_with_not_long_enough_name(): expected_validation_result=False, expected_triggered_requirements=["WorkflowExecution"], expected_triggered_issues=[ - "Workflow (CreateAction) MUST have a name string of at least 10 characters." + "WorkflowRun MUST have a name string of at least 10 characters." ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, @@ -203,7 +203,7 @@ def test_5src_workflow_object_with_no_action_status(): expected_triggered_requirements=["WorkflowExecution"], expected_triggered_issues=[ ( - "WorkflowExecution MUST have an actionStatus " + "WorkflowRun MUST have an actionStatus " "with an allowed value (see https://schema.org/ActionStatusType)." ) ], @@ -236,7 +236,7 @@ def test_5src_workflow_object_with_no_properly_valued_action_status(): expected_triggered_requirements=["WorkflowExecution"], expected_triggered_issues=[ ( - "WorkflowExecution MUST have an actionStatus " + "WorkflowRun MUST have an actionStatus " "with an allowed value (see https://schema.org/ActionStatusType)." ) ], @@ -267,7 +267,7 @@ def test_5src_workflow_object_not_mentioned_by_root_data_entity(): expected_validation_result=False, expected_triggered_requirements=["RootDataEntity"], expected_triggered_issues=[ - "RootDataEntity SHOULD mention workflow execution object (typed CreateAction)." + "RootDataEntity SHOULD mention workflow execution object (typed WorkflowRun)." ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, diff --git a/tests/integration/profiles/five-safes-crate/test_5src_2_requesting_agent.py b/tests/integration/profiles/five-safes-crate/test_5src_2_requesting_agent.py index ddc69f73..dc05cb65 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_2_requesting_agent.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_2_requesting_agent.py @@ -156,9 +156,9 @@ def test_5src_agent_does_not_have_affiliation(): rocrate_path=ValidROC().five_safes_crate_request, requirement_severity=Severity.RECOMMENDED, expected_validation_result=False, - expected_triggered_requirements=["Agent of CreateAction"], + expected_triggered_requirements=["Agent of WorkflowRun"], expected_triggered_issues=[ - "The agent of a CreateAction entity SHOULD have an affiliation" + "The agent of a WorkflowRun entity SHOULD have an affiliation" ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, diff --git a/tests/integration/profiles/five-safes-crate/test_5src_7_requesting_workflow_run.py b/tests/integration/profiles/five-safes-crate/test_5src_7_requesting_workflow_run.py index 654187ad..ea9bc114 100644 --- a/tests/integration/profiles/five-safes-crate/test_5src_7_requesting_workflow_run.py +++ b/tests/integration/profiles/five-safes-crate/test_5src_7_requesting_workflow_run.py @@ -52,7 +52,8 @@ def test_rocrate_does_not_have_createaction(): expected_validation_result=False, expected_triggered_requirements=["RootDataEntity"], expected_triggered_issues=[ - "`RootDataEntity` MUST reference at least one `CreateAction` through `mentions`" + "`RootDataEntity` MUST reference at least one `WorkflowRun` through `mentions`", + "The crate MUST contain at least one `WorkflowRun` entity", ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, @@ -82,7 +83,7 @@ def test_rootdataentity_does_not_have_mentions_property(): expected_validation_result=False, expected_triggered_requirements=["RootDataEntity"], expected_triggered_issues=[ - "`RootDataEntity` MUST reference at least one `CreateAction` through `mentions`" + "`RootDataEntity` MUST reference at least one `WorkflowRun` through `mentions`" ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, @@ -115,73 +116,7 @@ def test_rootdataentity_does_not_mention_create_action(): expected_validation_result=False, expected_triggered_requirements=["RootDataEntity"], expected_triggered_issues=[ - "`RootDataEntity` MUST reference at least one `CreateAction` through `mentions`" - ], - profile_identifier="five-safes-crate", - rocrate_entity_mod_sparql=sparql, - ) - - -def test_createaction_does_not_have_instrument_property(): - """ - Test a Five Safes Crate where `CreateAction` does not have the property `instrument`. - (We remove the property `instrument` from the `CreateAction` entity) - """ - sparql = ( - SPARQL_PREFIXES - + """ - DELETE { - ?action schema:instrument ?o . - } - WHERE { - ?action schema:instrument ?o ; - a schema:CreateAction . - } - """ - ) - - do_entity_test( - rocrate_path=ValidROC().five_safes_crate_request, - requirement_severity=Severity.REQUIRED, - expected_validation_result=False, - expected_triggered_requirements=["CreateAction"], - expected_triggered_issues=[ - "`CreateAction` MUST have the `instrument` property" - ], - profile_identifier="five-safes-crate", - rocrate_entity_mod_sparql=sparql, - ) - - -def test_createaction_does_not_reference_mainentity_via_instrument(): - """ - Test a Five Safes Crate where `CreateAction` --> `instrument` does not - reference `mainEntity`. - (We replace `mainEntity` with a literal as the object of `CreateAction` --> `instrument`) - """ - sparql = ( - SPARQL_PREFIXES - + """ - DELETE { - ?action schema:instrument ?o . - } - INSERT { - ?action schema:instrument "This is not the mainEntity" . - } - WHERE { - ?action schema:instrument ?o ; - a schema:CreateAction . - } - """ - ) - - do_entity_test( - rocrate_path=ValidROC().five_safes_crate_request, - requirement_severity=Severity.REQUIRED, - expected_validation_result=False, - expected_triggered_requirements=["CreateAction"], - expected_triggered_issues=[ - "`CreateAction` --> `instrument` MUST reference the same entity as `Root Data Entity` --> `mainEntity`" + "`RootDataEntity` MUST reference at least one `WorkflowRun` through `mentions`" ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, @@ -214,9 +149,9 @@ def test_createaction_object_does_not_reference_existing_entities(): rocrate_path=ValidROC().five_safes_crate_request, requirement_severity=Severity.REQUIRED, expected_validation_result=False, - expected_triggered_requirements=["CreateAction"], + expected_triggered_requirements=["WorkflowRun"], expected_triggered_issues=[ - "Each `object` in `CreateAction` MUST reference an existing entity." + "Each `object` in `WorkflowRun` MUST reference an existing entity." ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, @@ -248,9 +183,9 @@ def test_createaction_does_not_have_object_property(): rocrate_path=ValidROC().five_safes_crate_request, requirement_severity=Severity.RECOMMENDED, expected_validation_result=False, - expected_triggered_requirements=["CreateAction"], + expected_triggered_requirements=["WorkflowRun"], expected_triggered_issues=[ - "`CreateAction` SHOULD have the property `object` with IRI values." + "`WorkflowRun` SHOULD have the property `object` with IRI values." ], profile_identifier="five-safes-crate", rocrate_entity_mod_sparql=sparql, diff --git a/tests/shared.py b/tests/shared.py index c6d76af0..ee49733c 100644 --- a/tests/shared.py +++ b/tests/shared.py @@ -118,9 +118,9 @@ def do_entity_test( Additional keyword arguments (kwargs) are passed along to initialise ValidationSettings. """ - assert not ( - rocrate_entity_patch and rocrate_entity_mod_sparql - ), "Cannot use rocrate_entity_patch and rocrate_entity_mod_sparql together" + assert not (rocrate_entity_patch and rocrate_entity_mod_sparql), ( + "Cannot use rocrate_entity_patch and rocrate_entity_mod_sparql together" + ) # declare variables failed_requirements = None @@ -198,9 +198,9 @@ def do_entity_test( assert result.context is not None, "Validation context should not be None" f"Expected requirement severity to be {requirement_severity}, but got {result.context.requirement_severity}" - assert ( - result.passed() == expected_validation_result - ), f"RO-Crate should be {'valid' if expected_validation_result else 'invalid'}" + assert result.passed() == expected_validation_result, ( + f"RO-Crate should be {'valid' if expected_validation_result else 'invalid'}" + ) # check requirement failed_requirements = [_.name for _ in result.failed_requirements] @@ -228,9 +228,9 @@ def do_entity_test( if not any( expected_issue in issue for issue in detected_issues ): # support partial match - assert ( - False - ), f'The expected issue "{expected_issue}" was not found in the detected issues' + assert False, ( + f'The expected issue "{expected_issue}" was not found in the detected issues' + ) except Exception as e: if logger.isEnabledFor(logging.DEBUG): logger.exception(e)