592 lines
21 KiB
Markdown
592 lines
21 KiB
Markdown
|
|
# Pernod Ricard Data MetaModel — T-Box Processbook
|
||
|
|
|
||
|
|
**Version 0.1** — Draft for review — generated 2026-08-03
|
||
|
|
|
||
|
|
> Generated from `processes.yaml`. The BPMN files in `bpmn/` are the authoritative form; the views below are derived from the same source. Do not edit this document (EV-007, EV-008).
|
||
|
|
|
||
|
|
Procedures for changing the vocabulary of the model. Each procedure names the rules it enforces, the steps a person must perform, and the points at which the work stops rather than continues.
|
||
|
|
|
||
|
|
## Procedures
|
||
|
|
|
||
|
|
| Id | Family | Procedure | Scope |
|
||
|
|
|---|---|---|---|
|
||
|
|
| **X1** | Release | Propagate a change and publish a version | Any validated modification of the vocabulary. |
|
||
|
|
| **C1** | Create | Create a term | class | relation | attribute | annotation |
|
||
|
|
| **C2** | Create | Create a controlled value | typed individual | literal |
|
||
|
|
| **C3** | Create | Create a shape | Any SHACL constraint added to the validation set. |
|
||
|
|
| **D1** | Delete | Deprecate a term | class | relation | attribute | annotation | individual |
|
||
|
|
| **D2** | Delete | Withdraw a term permanently | class | relation | attribute | annotation | individual |
|
||
|
|
| **R1** | Verify | Verify the vocabulary against the rulebook | The whole vocabulary, or the subset touched by a change. |
|
||
|
|
| **R2** | Verify | Validate instances against the shapes | Any instance graph in the validation perimeter. |
|
||
|
|
| **R3** | Verify | Audit what the shapes cannot see | The whole vocabulary and its source file. |
|
||
|
|
|
||
|
|
## Reading a diagram
|
||
|
|
|
||
|
|
- A **rounded** node is a start or end state.
|
||
|
|
- A **diamond** is a decision; every outgoing path is labelled.
|
||
|
|
- A **shaded** box is a human task: it cannot be automated, and the work stops there until someone acts.
|
||
|
|
- A **double-bordered** box calls another procedure by its identifier.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# X1 — Propagate a change and publish a version
|
||
|
|
|
||
|
|
| | |
|
||
|
|
|---|---|
|
||
|
|
| Family | Release |
|
||
|
|
| Scope | Any validated modification of the vocabulary. |
|
||
|
|
| Trigger | A change to the vocabulary has been agreed and is ready to apply. |
|
||
|
|
| Inputs | the agreed change, the target version, the list of affected artifacts |
|
||
|
|
| Outputs | a merged branch, a tagged version, an execution log |
|
||
|
|
| Rules enforced | EV-004, EV-005, EV-006, EV-007, EV-008, EV-009, EV-010, EV-014, EV-015, TN-023 |
|
||
|
|
| Calls | R1, R2 |
|
||
|
|
|
||
|
|
**Note.** The most frequently invoked procedure of the processbook: every other procedure ends by calling it. Two of its steps are gateways rather than checks, because an idempotence failure and a validation failure must stop the work rather than be noted in passing.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
start(["Change agreed"])
|
||
|
|
branch["Create the migration branch"]
|
||
|
|
apply["Apply the change through an RDF parser"]
|
||
|
|
labels["Regenerate labels by derivation"]
|
||
|
|
abox["Propagate to the instances"]
|
||
|
|
shapes["Update the shapes and align conformsTo"]
|
||
|
|
artifacts["Regenerate every derived artifact"]
|
||
|
|
replay["Replay the chain a second time"]
|
||
|
|
idem{"Second run reports zero change?"}
|
||
|
|
verify_voc[["R1: Verify the vocabulary"]]
|
||
|
|
verify_abox[["R2: Validate the instances"]]
|
||
|
|
log["Write the execution log for this attempt"]
|
||
|
|
clean{"Any violation?"}
|
||
|
|
decide["Correct or abandon"]
|
||
|
|
drop["Destroy the branch and restart from the published version"]
|
||
|
|
review["Review the merge"]
|
||
|
|
merge["Merge as a block"]
|
||
|
|
bump["Increment the ontology version"]
|
||
|
|
end(["Version published"])
|
||
|
|
aborted(["Change abandoned"])
|
||
|
|
start --> branch
|
||
|
|
branch --> apply
|
||
|
|
apply --> labels
|
||
|
|
labels --> abox
|
||
|
|
abox --> shapes
|
||
|
|
shapes --> artifacts
|
||
|
|
artifacts --> replay
|
||
|
|
replay --> idem
|
||
|
|
idem -->|zero change| verify_voc
|
||
|
|
idem -->|the chain is not replayable| decide
|
||
|
|
verify_voc --> verify_abox
|
||
|
|
verify_abox --> log
|
||
|
|
log --> clean
|
||
|
|
clean -->|none| review
|
||
|
|
clean -->|at least one| decide
|
||
|
|
decide -->|correct| apply
|
||
|
|
decide -->|abandon| drop
|
||
|
|
drop --> aborted
|
||
|
|
review --> merge
|
||
|
|
merge --> bump
|
||
|
|
bump --> end
|
||
|
|
class idem decision;
|
||
|
|
class clean decision;
|
||
|
|
class decide human;
|
||
|
|
class review human;
|
||
|
|
classDef human fill:#FFF4CE,stroke:#B08900;
|
||
|
|
classDef decision fill:#E8F0F7,stroke:#3E6E96;
|
||
|
|
```
|
||
|
|
|
||
|
|
| Step | Type | Rules |
|
||
|
|
|---|---|---|
|
||
|
|
| Create the migration branch | script | EV-009 |
|
||
|
|
| Apply the change through an RDF parser | script | EV-005, EV-006 |
|
||
|
|
| Regenerate labels by derivation | script | TN-023 |
|
||
|
|
| Propagate to the instances | script | EV-009 |
|
||
|
|
| Update the shapes and align conformsTo | script | EV-010 |
|
||
|
|
| Regenerate every derived artifact | script | EV-008 |
|
||
|
|
| Replay the chain a second time | script | EV-006, EV-007 |
|
||
|
|
| Second run reports zero change? | decision | - |
|
||
|
|
| Verify the vocabulary (R1) | calls | - |
|
||
|
|
| Validate the instances (R2) | calls | - |
|
||
|
|
| Write the execution log for this attempt | script | EV-015 |
|
||
|
|
| Any violation? | decision | - |
|
||
|
|
| Correct or abandon | human | EV-004, EV-007 |
|
||
|
|
| Destroy the branch and restart from the published version | script | EV-007 |
|
||
|
|
| Review the merge | human | EV-004, EV-009 |
|
||
|
|
| Merge as a block | script | EV-009 |
|
||
|
|
| Increment the ontology version | script | EV-014 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# C1 — Create a term
|
||
|
|
|
||
|
|
| | |
|
||
|
|
|---|---|
|
||
|
|
| Family | Create |
|
||
|
|
| Scope | class | relation | attribute | annotation |
|
||
|
|
| Trigger | A missing concept, edge or field has been identified. |
|
||
|
|
| Inputs | the intended meaning, the nature, the target layer, the provenance, the parent or the domain and range |
|
||
|
|
| Outputs | a declared term, a published version |
|
||
|
|
| Rules enforced | EV-004, TN-001, TN-002, TN-003, TN-004, TN-005, TN-006, TN-007, TN-009, TN-010, TN-011, TN-012, TN-013, TN-014, TN-015, TN-018, TN-019, TN-020, TN-021, TN-022, TN-023, TN-024, TN-025, TN-026, TN-027, TN-028 |
|
||
|
|
| Calls | R1, X1 |
|
||
|
|
|
||
|
|
**Parameter.** The nature of the term selects the naming rules applied at the naming step: a class takes TN-001, TN-002, TN-004, TN-005, TN-006, TN-007 and TN-027; a relation takes TN-001, TN-002, TN-009, TN-010, TN-011 and TN-028; an attribute takes TN-001, TN-002, TN-004, TN-012, TN-013, TN-014 and TN-015; an annotation takes TN-001, TN-002 and TN-003.
|
||
|
|
|
||
|
|
**Note.** The first step has no tool today. Checking that no existing term already covers the need is the semantic uniqueness control that SHACL cannot perform, and it stays a human task until R3 exists.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
start(["Need identified"])
|
||
|
|
unique["Check that no existing term covers the need"]
|
||
|
|
exists{"A term already covers it?"}
|
||
|
|
reuse(["Reuse the existing term"])
|
||
|
|
name["Name the term according to its nature"]
|
||
|
|
label["Derive the label"]
|
||
|
|
short["Decide the short label and the acronym"]
|
||
|
|
comment["Write the comment"]
|
||
|
|
declare["Declare typing"]
|
||
|
|
validate["Validate before applying"]
|
||
|
|
check[["R1: Verify against the rulebook"]]
|
||
|
|
release[["X1: Propagate and publish"]]
|
||
|
|
end(["Term available"])
|
||
|
|
start --> unique
|
||
|
|
unique --> exists
|
||
|
|
exists -->|yes| reuse
|
||
|
|
exists -->|no| name
|
||
|
|
name --> label
|
||
|
|
label --> short
|
||
|
|
short --> comment
|
||
|
|
comment --> declare
|
||
|
|
declare --> validate
|
||
|
|
validate --> check
|
||
|
|
check --> release
|
||
|
|
release --> end
|
||
|
|
class unique human;
|
||
|
|
class exists decision;
|
||
|
|
class short human;
|
||
|
|
class comment human;
|
||
|
|
class validate human;
|
||
|
|
classDef human fill:#FFF4CE,stroke:#B08900;
|
||
|
|
classDef decision fill:#E8F0F7,stroke:#3E6E96;
|
||
|
|
```
|
||
|
|
|
||
|
|
| Step | Type | Rules |
|
||
|
|
|---|---|---|
|
||
|
|
| Check that no existing term covers the need | human | - |
|
||
|
|
| A term already covers it? | decision | - |
|
||
|
|
| Name the term according to its nature | script | TN-001, TN-002, TN-003, TN-004, TN-005, TN-006, TN-009, TN-010, TN-011, TN-012, TN-013, TN-014, TN-015, TN-028 |
|
||
|
|
| Derive the label | script | TN-018, TN-019, TN-020, TN-021, TN-023 |
|
||
|
|
| Decide the short label and the acronym | human | TN-022 |
|
||
|
|
| Write the comment | human | TN-024 |
|
||
|
|
| Declare typing | script | TN-007, TN-025, TN-026, TN-027 |
|
||
|
|
| Validate before applying | human | EV-004 |
|
||
|
|
| Verify against the rulebook (R1) | calls | - |
|
||
|
|
| Propagate and publish (X1) | calls | - |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# C2 — Create a controlled value
|
||
|
|
|
||
|
|
| | |
|
||
|
|
|---|---|
|
||
|
|
| Family | Create |
|
||
|
|
| Scope | typed individual | literal |
|
||
|
|
| Trigger | A new value is needed in a controlled set. |
|
||
|
|
| Inputs | the value, the set it belongs to, whether a domain may add others |
|
||
|
|
| Outputs | a declared value, a published version |
|
||
|
|
| Rules enforced | EV-004, TN-001, TN-016, TN-017, TN-018, TN-022 |
|
||
|
|
| Calls | C3, R1, X1 |
|
||
|
|
|
||
|
|
**Parameter.** The form is not a style choice but the outcome of the first decision. The two branches have different consequences: the literal branch edits the shapes and therefore the vocabulary, so it falls under the version freeze; the individual branch touches nothing else.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
start(["New value needed"])
|
||
|
|
decide["Must it be defined, owned or extended by a domain?"]
|
||
|
|
form{"Which form?"}
|
||
|
|
indiv["Create the typed individual and derive its label"]
|
||
|
|
literal["Write the literal in upper snake case"]
|
||
|
|
shape[["C3: Extend the closed list in the shapes"]]
|
||
|
|
validate["Validate before applying"]
|
||
|
|
check[["R1: Verify against the rulebook"]]
|
||
|
|
release[["X1: Propagate and publish"]]
|
||
|
|
end(["Value available"])
|
||
|
|
start --> decide
|
||
|
|
decide --> form
|
||
|
|
form -->|extensible by a domain| indiv
|
||
|
|
form -->|closed governance state| literal
|
||
|
|
indiv --> validate
|
||
|
|
literal --> shape
|
||
|
|
shape --> validate
|
||
|
|
validate --> check
|
||
|
|
check --> release
|
||
|
|
release --> end
|
||
|
|
class decide human;
|
||
|
|
class form decision;
|
||
|
|
class validate human;
|
||
|
|
classDef human fill:#FFF4CE,stroke:#B08900;
|
||
|
|
classDef decision fill:#E8F0F7,stroke:#3E6E96;
|
||
|
|
```
|
||
|
|
|
||
|
|
| Step | Type | Rules |
|
||
|
|
|---|---|---|
|
||
|
|
| Must it be defined, owned or extended by a domain? | human | TN-016 |
|
||
|
|
| Which form? | decision | - |
|
||
|
|
| Create the typed individual and derive its label | script | TN-001, TN-018, TN-022 |
|
||
|
|
| Write the literal in upper snake case | script | TN-017 |
|
||
|
|
| Extend the closed list in the shapes (C3) | calls | - |
|
||
|
|
| Validate before applying | human | EV-004 |
|
||
|
|
| Verify against the rulebook (R1) | calls | - |
|
||
|
|
| Propagate and publish (X1) | calls | - |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# C3 — Create a shape
|
||
|
|
|
||
|
|
| | |
|
||
|
|
|---|---|
|
||
|
|
| Family | Create |
|
||
|
|
| Scope | Any SHACL constraint added to the validation set. |
|
||
|
|
| Trigger | A rule needs an executor, or a new class enters the validation perimeter. |
|
||
|
|
| Inputs | the rule to enforce, the target class or property |
|
||
|
|
| Outputs | a shape, a rulebook entry naming it as executor |
|
||
|
|
| Rules enforced | EV-010, EV-011, EV-012, EV-013 |
|
||
|
|
| Calls | R2, X1 |
|
||
|
|
|
||
|
|
**Note.** The step that is forgotten is the last one before release: recording the shape as the executor of its rule. Without it a rule stays declared blocking with nothing enforcing it, which EV-011 forbids.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
start(["Constraint needed"])
|
||
|
|
write["Write the constraint"]
|
||
|
|
pattern["Check that every pattern is expressed positively"]
|
||
|
|
portable{"Expressible within the specification?"}
|
||
|
|
demote["Move the rule to the script tier"]
|
||
|
|
conforms["Align the declared ontology version"]
|
||
|
|
test[["R2: Test against real instances"]]
|
||
|
|
record["Record the shape as the executor of its rule"]
|
||
|
|
release[["X1: Propagate and publish"]]
|
||
|
|
end(["Shape in force"])
|
||
|
|
start --> write
|
||
|
|
write --> pattern
|
||
|
|
pattern --> portable
|
||
|
|
portable -->|yes| conforms
|
||
|
|
portable -->|no| demote
|
||
|
|
demote --> record
|
||
|
|
conforms --> test
|
||
|
|
test --> record
|
||
|
|
record --> release
|
||
|
|
release --> end
|
||
|
|
class write human;
|
||
|
|
class portable decision;
|
||
|
|
class demote human;
|
||
|
|
class record human;
|
||
|
|
classDef human fill:#FFF4CE,stroke:#B08900;
|
||
|
|
classDef decision fill:#E8F0F7,stroke:#3E6E96;
|
||
|
|
```
|
||
|
|
|
||
|
|
| Step | Type | Rules |
|
||
|
|
|---|---|---|
|
||
|
|
| Write the constraint | human | - |
|
||
|
|
| Check that every pattern is expressed positively | script | EV-013 |
|
||
|
|
| Expressible within the specification? | decision | - |
|
||
|
|
| Move the rule to the script tier | human | EV-012 |
|
||
|
|
| Align the declared ontology version | script | EV-010 |
|
||
|
|
| Test against real instances (R2) | calls | - |
|
||
|
|
| Record the shape as the executor of its rule | human | EV-011, EV-012 |
|
||
|
|
| Propagate and publish (X1) | calls | - |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# D1 — Deprecate a term
|
||
|
|
|
||
|
|
| | |
|
||
|
|
|---|---|
|
||
|
|
| Family | Delete |
|
||
|
|
| Scope | class | relation | attribute | annotation | individual |
|
||
|
|
| Trigger | A term is superseded or no longer needed. |
|
||
|
|
| Inputs | the term, its replacement if any |
|
||
|
|
| Outputs | a deprecated stub, a published version |
|
||
|
|
| Rules enforced | EV-001, EV-015, TN-020 |
|
||
|
|
| Calls | X1 |
|
||
|
|
|
||
|
|
**Note.** The count at step two is informative, not a condition: a term may be deprecated whether or not it is instantiated. It becomes a condition only in D2.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
start(["Term superseded"])
|
||
|
|
replacement["Identify the replacement"]
|
||
|
|
count["Count the instances for information"]
|
||
|
|
mark["Mark deprecated and declare the replacement"]
|
||
|
|
strip["Strip the stub of every edge"]
|
||
|
|
label["Remove any mention of state from the label"]
|
||
|
|
release[["X1: Propagate and publish"]]
|
||
|
|
end(["Term deprecated"])
|
||
|
|
start --> replacement
|
||
|
|
replacement --> count
|
||
|
|
count --> mark
|
||
|
|
mark --> strip
|
||
|
|
strip --> label
|
||
|
|
label --> release
|
||
|
|
release --> end
|
||
|
|
class replacement human;
|
||
|
|
classDef human fill:#FFF4CE,stroke:#B08900;
|
||
|
|
classDef decision fill:#E8F0F7,stroke:#3E6E96;
|
||
|
|
```
|
||
|
|
|
||
|
|
| Step | Type | Rules |
|
||
|
|
|---|---|---|
|
||
|
|
| Identify the replacement | human | - |
|
||
|
|
| Count the instances for information | script | EV-015 |
|
||
|
|
| Mark deprecated and declare the replacement | script | EV-001 |
|
||
|
|
| Strip the stub of every edge | script | EV-001 |
|
||
|
|
| Remove any mention of state from the label | script | TN-020 |
|
||
|
|
| Propagate and publish (X1) | calls | - |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# D2 — Withdraw a term permanently
|
||
|
|
|
||
|
|
| | |
|
||
|
|
|---|---|
|
||
|
|
| Family | Delete |
|
||
|
|
| Scope | class | relation | attribute | annotation | individual |
|
||
|
|
| Trigger | A deprecated term is to be removed from the vocabulary. |
|
||
|
|
| Inputs | the deprecated term |
|
||
|
|
| Outputs | a vocabulary without the term, a proof of non-instantiation, a published version |
|
||
|
|
| Rules enforced | EV-002, EV-003, EV-015 |
|
||
|
|
| Calls | R1, R2, X1 |
|
||
|
|
|
||
|
|
**Note.** The reference cleaning step is what prevents phantom nodes: a subject removed while its identifier is still cited elsewhere is reconstructed by inference, present in traversals and absent from every control. It is a step of the procedure, not a check at the end of a script.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
start(["Withdrawal requested"])
|
||
|
|
count["Run the counting query"]
|
||
|
|
instantiated{"Any instance found?"}
|
||
|
|
keep(["Kept deprecated"])
|
||
|
|
proof["Attach the proof to the commit"]
|
||
|
|
remove["Remove the subject block"]
|
||
|
|
refs["Remove every reference naming the subject"]
|
||
|
|
check_voc[["R1: Verify the vocabulary"]]
|
||
|
|
check_abox[["R2: Validate the instances"]]
|
||
|
|
release[["X1: Propagate and publish"]]
|
||
|
|
end(["Term withdrawn"])
|
||
|
|
start --> count
|
||
|
|
count --> instantiated
|
||
|
|
instantiated -->|yes| keep
|
||
|
|
instantiated -->|no| proof
|
||
|
|
proof --> remove
|
||
|
|
remove --> refs
|
||
|
|
refs --> check_voc
|
||
|
|
check_voc --> check_abox
|
||
|
|
check_abox --> release
|
||
|
|
release --> end
|
||
|
|
class instantiated decision;
|
||
|
|
classDef human fill:#FFF4CE,stroke:#B08900;
|
||
|
|
classDef decision fill:#E8F0F7,stroke:#3E6E96;
|
||
|
|
```
|
||
|
|
|
||
|
|
| Step | Type | Rules |
|
||
|
|
|---|---|---|
|
||
|
|
| Run the counting query | script | EV-002, EV-015 |
|
||
|
|
| Any instance found? | decision | - |
|
||
|
|
| Attach the proof to the commit | script | EV-002, EV-015 |
|
||
|
|
| Remove the subject block | script | - |
|
||
|
|
| Remove every reference naming the subject | script | EV-003 |
|
||
|
|
| Verify the vocabulary (R1) | calls | - |
|
||
|
|
| Validate the instances (R2) | calls | - |
|
||
|
|
| Propagate and publish (X1) | calls | - |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# R1 — Verify the vocabulary against the rulebook
|
||
|
|
|
||
|
|
| | |
|
||
|
|
|---|---|
|
||
|
|
| Family | Verify |
|
||
|
|
| Scope | The whole vocabulary, or the subset touched by a change. |
|
||
|
|
| Trigger | A term has been created, changed or withdrawn, or a release is prepared. |
|
||
|
|
| Inputs | the vocabulary, the rulebook source |
|
||
|
|
| Outputs | a conformance report |
|
||
|
|
| Rules enforced | EV-014, TN-001, TN-002, TN-003, TN-004, TN-005, TN-006, TN-007, TN-008, TN-009, TN-010, TN-011, TN-012, TN-013, TN-014, TN-015, TN-016, TN-017, TN-018, TN-019, TN-020, TN-021, TN-022, TN-023, TN-024, TN-025, TN-026, TN-027, TN-028 |
|
||
|
|
| Calls | - |
|
||
|
|
|
||
|
|
**Note.** Two tiers run in sequence, not in parallel: the script settles everything mechanisable, and a person answers only for the rules no script can judge. Reversing the order wastes review time on findings the script would have caught.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
start(["Verification requested"])
|
||
|
|
script["Run the naming and declaration checks"]
|
||
|
|
mechanised{"Any mechanised violation?"}
|
||
|
|
report_fail(["Report returned with violations"])
|
||
|
|
human["Review the rules no script can judge"]
|
||
|
|
judged{"Reviewer raises an issue?"}
|
||
|
|
report_ok(["Vocabulary conforms"])
|
||
|
|
start --> script
|
||
|
|
script --> mechanised
|
||
|
|
mechanised -->|at least one| report_fail
|
||
|
|
mechanised -->|none| human
|
||
|
|
human --> judged
|
||
|
|
judged -->|yes| report_fail
|
||
|
|
judged -->|no| report_ok
|
||
|
|
class mechanised decision;
|
||
|
|
class human human;
|
||
|
|
class judged decision;
|
||
|
|
classDef human fill:#FFF4CE,stroke:#B08900;
|
||
|
|
classDef decision fill:#E8F0F7,stroke:#3E6E96;
|
||
|
|
```
|
||
|
|
|
||
|
|
| Step | Type | Rules |
|
||
|
|
|---|---|---|
|
||
|
|
| Run the naming and declaration checks | script | TN-001, TN-002, TN-003, TN-004, TN-005, TN-006, TN-007, TN-009, TN-010, TN-011, TN-012, TN-013, TN-014, TN-015, TN-017, TN-018, TN-019, TN-020, TN-021, TN-023, TN-025, TN-026, TN-027, TN-028, EV-014 |
|
||
|
|
| Any mechanised violation? | decision | - |
|
||
|
|
| Review the rules no script can judge | human | TN-008, TN-016, TN-022, TN-024 |
|
||
|
|
| Reviewer raises an issue? | decision | - |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# R2 — Validate instances against the shapes
|
||
|
|
|
||
|
|
| | |
|
||
|
|
|---|---|
|
||
|
|
| Family | Verify |
|
||
|
|
| Scope | Any instance graph in the validation perimeter. |
|
||
|
|
| Trigger | Instances have changed, shapes have changed, or a release is prepared. |
|
||
|
|
| Inputs | the instance graph, the shapes, the ontology |
|
||
|
|
| Outputs | a validation report |
|
||
|
|
| Rules enforced | EV-010 |
|
||
|
|
| Calls | - |
|
||
|
|
|
||
|
|
**Note.** The version check comes first and aborts rather than warns. Validating against shapes that target another version of the ontology does not fail loudly: it returns a long list of violations that reads exactly like a regression of the model.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
start(["Validation requested"])
|
||
|
|
conforms["Compare the declared target version with the ontology version"]
|
||
|
|
match{"Versions match?"}
|
||
|
|
abort(["Aborted on version mismatch"])
|
||
|
|
run["Run the shape validation"]
|
||
|
|
violations{"Any violation?"}
|
||
|
|
fail(["Report returned with violations"])
|
||
|
|
ok(["Instances conform"])
|
||
|
|
start --> conforms
|
||
|
|
conforms --> match
|
||
|
|
match -->|no| abort
|
||
|
|
match -->|yes| run
|
||
|
|
run --> violations
|
||
|
|
violations -->|at least one| fail
|
||
|
|
violations -->|none| ok
|
||
|
|
class match decision;
|
||
|
|
class violations decision;
|
||
|
|
classDef human fill:#FFF4CE,stroke:#B08900;
|
||
|
|
classDef decision fill:#E8F0F7,stroke:#3E6E96;
|
||
|
|
```
|
||
|
|
|
||
|
|
| Step | Type | Rules |
|
||
|
|
|---|---|---|
|
||
|
|
| Compare the declared target version with the ontology version | script | EV-010 |
|
||
|
|
| Versions match? | decision | - |
|
||
|
|
| Run the shape validation | script | - |
|
||
|
|
| Any violation? | decision | - |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# R3 — Audit what the shapes cannot see
|
||
|
|
|
||
|
|
| | |
|
||
|
|
|---|---|
|
||
|
|
| Family | Verify |
|
||
|
|
| Scope | The whole vocabulary and its source file. |
|
||
|
|
| Trigger | Periodic audit, or before a version is published. |
|
||
|
|
| Inputs | the vocabulary, its source file |
|
||
|
|
| Outputs | a shortlist of suspected duplicates, a list of duplicated blocks |
|
||
|
|
| Rules enforced | EV-012 |
|
||
|
|
| Calls | - |
|
||
|
|
|
||
|
|
**Note.** Shape validation reads a graph, not a file and not meaning. Two identifiers standing for the same notion produce two individually valid graphs; a duplicated block of text produces identical triples and no complaint. This procedure is the tier those rules fall to, and its output is a shortlist for a person rather than a verdict.
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
start(["Audit requested"])
|
||
|
|
index["Build the normalised label index"]
|
||
|
|
hash["Hash every normalised subject block"]
|
||
|
|
shortlist{"Any candidate found?"}
|
||
|
|
clean(["Nothing to arbitrate"])
|
||
|
|
review["Arbitrate each candidate"]
|
||
|
|
act{"Duplication confirmed?"}
|
||
|
|
merge(["Referred to the merge procedure"])
|
||
|
|
dismissed(["Candidates dismissed"])
|
||
|
|
start --> index
|
||
|
|
index --> hash
|
||
|
|
hash --> shortlist
|
||
|
|
shortlist -->|none| clean
|
||
|
|
shortlist -->|at least one| review
|
||
|
|
review --> act
|
||
|
|
act -->|yes| merge
|
||
|
|
act -->|no| dismissed
|
||
|
|
class shortlist decision;
|
||
|
|
class review human;
|
||
|
|
class act decision;
|
||
|
|
classDef human fill:#FFF4CE,stroke:#B08900;
|
||
|
|
classDef decision fill:#E8F0F7,stroke:#3E6E96;
|
||
|
|
```
|
||
|
|
|
||
|
|
| Step | Type | Rules |
|
||
|
|
|---|---|---|
|
||
|
|
| Build the normalised label index | script | EV-012 |
|
||
|
|
| Hash every normalised subject block | script | EV-012 |
|
||
|
|
| Any candidate found? | decision | - |
|
||
|
|
| Arbitrate each candidate | human | - |
|
||
|
|
| Duplication confirmed? | decision | - |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
# Rule coverage
|
||
|
|
|
||
|
|
Which procedures enforce each rule. Derived, not maintained: a rule cited in a diagram appears here automatically.
|
||
|
|
|
||
|
|
| Rule | Procedures |
|
||
|
|
|---|---|
|
||
|
|
| EV-001 | D1 |
|
||
|
|
| EV-002 | D2 |
|
||
|
|
| EV-003 | D2 |
|
||
|
|
| EV-004 | C1, C2, X1 |
|
||
|
|
| EV-005 | X1 |
|
||
|
|
| EV-006 | X1 |
|
||
|
|
| EV-007 | X1 |
|
||
|
|
| EV-008 | X1 |
|
||
|
|
| EV-009 | X1 |
|
||
|
|
| EV-010 | C3, R2, X1 |
|
||
|
|
| EV-011 | C3 |
|
||
|
|
| EV-012 | C3, R3 |
|
||
|
|
| EV-013 | C3 |
|
||
|
|
| EV-014 | R1, X1 |
|
||
|
|
| EV-015 | D1, D2, X1 |
|
||
|
|
| TN-001 | C1, C2, R1 |
|
||
|
|
| TN-002 | C1, R1 |
|
||
|
|
| TN-003 | C1, R1 |
|
||
|
|
| TN-004 | C1, R1 |
|
||
|
|
| TN-005 | C1, R1 |
|
||
|
|
| TN-006 | C1, R1 |
|
||
|
|
| TN-007 | C1, R1 |
|
||
|
|
| TN-008 | R1 |
|
||
|
|
| TN-009 | C1, R1 |
|
||
|
|
| TN-010 | C1, R1 |
|
||
|
|
| TN-011 | C1, R1 |
|
||
|
|
| TN-012 | C1, R1 |
|
||
|
|
| TN-013 | C1, R1 |
|
||
|
|
| TN-014 | C1, R1 |
|
||
|
|
| TN-015 | C1, R1 |
|
||
|
|
| TN-016 | C2, R1 |
|
||
|
|
| TN-017 | C2, R1 |
|
||
|
|
| TN-018 | C1, C2, R1 |
|
||
|
|
| TN-019 | C1, R1 |
|
||
|
|
| TN-020 | C1, D1, R1 |
|
||
|
|
| TN-021 | C1, R1 |
|
||
|
|
| TN-022 | C1, C2, R1 |
|
||
|
|
| TN-023 | C1, R1, X1 |
|
||
|
|
| TN-024 | C1, R1 |
|
||
|
|
| TN-025 | C1, R1 |
|
||
|
|
| TN-026 | C1, R1 |
|
||
|
|
| TN-027 | C1, R1 |
|
||
|
|
| TN-028 | C1, R1 |
|