tbox: v2.2 - polymorphisme declare sur 19 proprietes, 17 domaines poses, provenance portee par les classes concretes, GovernanceLayerObject rattachee, affectations de gouvernance completes (12 completees, 10 SDO, 1 PO, 16 stewards par objet metier), Panel Coverage gouverne. Validation SHACL sans violation bloquante

This commit is contained in:
Bastien Gourdon
2026-08-07 10:31:16 +02:00
parent d90d2a316d
commit 0b7d3834d2
29 changed files with 3274 additions and 274 deletions
+14 -13
View File
@@ -1,6 +1,6 @@
# Pernod Ricard Data MetaModel — T-Box Rulebook
**Version 1.2** — Draft for review — generated 2026-08-03
**Version 1.4** — Draft for review — generated 2026-08-03
> Generated from `rules.yaml`. Do not edit this document: edit the source and regenerate (EV-007, EV-008).
@@ -188,7 +188,7 @@ The IRI is identity. It is immutable in the RDF sense — changing one is a migr
## TN-009 — A relation begins with a verb
**Statement.** The local name of an object property begins with a verb, in lower case. Both the active form and the passive or participial form are admitted: a past participle is a verb in first position. No relation begins with a preposition or with a noun.
**Statement.** The local name of an object property begins with a verb, in lower case. Both the active form and the passive or participial form are admitted: a past participle is a verb in first position. An adverb qualifying that verb is transparent and may precede it. No relation begins with a preposition or with a noun.
| | |
|---|---|
@@ -198,12 +198,12 @@ The IRI is identity. It is immutable in the RDF sense — changing one is a migr
| Executor | `check_tbox_naming.py` |
| Procedure | _pending_ |
**Why.** A relation reads as a verb and an attribute reads as a noun. The distinction is what lets a reader tell an edge from a field without opening the declaration. The explicit clause on participial forms is required: read literally, a verb-first rule would condemn a whole family of sound relations such as computedBy, storedIn and derivedFrom.
**Why.** A relation reads as a verb and an attribute reads as a noun. The distinction is what lets a reader tell an edge from a field without opening the declaration. Two clauses are stated rather than left implicit, because a literal reading would condemn sound relations: the participial one, which covers a whole family such as computedBy, storedIn and derivedFrom, and the adverbial one, which covers a relation whose verb is qualified rather than replaced.
| From | To | Note |
|---|---|---|
| pr:inDatabase | pr:isInDatabase | a preposition is not a verb |
| pr:primaryLocation | pr:primarilyStoredIn | a noun is not a verb |
| pr:primaryLocation | pr:primarilyStoredIn | a noun is not a verb; the adverb is transparent and the verb follows |
| pr:computedBy | pr:computedBy | participial form is conforming |
## TN-010 — The is prefix is either a copula or a predicate
@@ -507,7 +507,7 @@ Nothing is left to be guessed. What a term is, what it applies to, where it sits
## TN-025 — Every property declares its domain and range
**Statement.** rdfs:domain and rdfs:range are mandatory on every property, EXCEPT where the property is deliberately polymorphic. A polymorphic property states so in its comment and has its scope declared in SHACL. Silent absence is a violation; documented absence is not.
**Statement.** rdfs:domain and rdfs:range are mandatory on every property, EXCEPT where the property is deliberately polymorphic. A polymorphic property declares pr:polymorphic true and has its scope declared in SHACL. Silent absence is a violation; declared absence is not.
| | |
|---|---|
@@ -517,30 +517,31 @@ Nothing is left to be guessed. What a term is, what it applies to, where it sits
| Executor | `check_tbox_naming.py` |
| Procedure | _pending_ |
**Why.** A property with no domain cannot be targeted by any control. But some properties are polymorphic by design, their scope controlled class by class in SHACL rather than by twin properties; giving those an rdfs:domain would trigger the RDFS retyping described in TN-028. The rule therefore separates the two cases rather than demanding a domain everywhere.
**Why.** A property with no domain cannot be targeted by any control. But some properties are polymorphic by design, their scope controlled class by class in SHACL rather than by twin properties; giving those an rdfs:domain would trigger the RDFS retyping described in TN-028. The rule therefore separates the two cases rather than demanding a domain everywhere. The distinction is carried by an axiom and not by a sentence in the comment: a checker looking for a phrase in prose fails the moment someone words it differently, and what matters is declared rather than read, exactly as for abstractness.
| From | To | Note |
|---|---|---|
| a polymorphic property with no domain and no comment | violation | silence is indistinguishable from omission |
| a polymorphic property with no domain | conforming | scope declared in SHACL |
| a property with no domain and no declaration | violation | silence is indistinguishable from omission |
| a property with no domain, declaring pr:polymorphic true | conforming | scope declared in SHACL |
## TN-026 — Every term declares how it was authored
## TN-026 — Every concrete class declares how its instances are produced
**Statement.** pr:authoringMode is mandatory on every term. pr:harvestSource is mandatory if and only if the mode is HARVESTED.
**Statement.** Every CONCRETE CLASS declares pr:authoringMode, stating whether its instances are ASSERTED by governance or HARVESTED from a system. pr:harvestSource is mandatory if and only if the mode is HARVESTED. The declared mode agrees with the provenance axis the class descends from: a class under CapturedObject declares HARVESTED, one under DefinedObject declares ASSERTED. Nothing else carries the property: not an abstract class, not a property, not a term of the vocabulary in its own right.
| | |
|---|---|
| Severity | **BLOCKING** |
| Applies to | class, object_property, datatype_property, annotation_property |
| Applies to | class |
| Enforced at | script |
| Executor | `check_tbox_naming.py` |
| Procedure | _pending_ |
**Why.** Provenance decides who may edit a term and what a divergence means. A term stating where its data comes from without stating that it is harvested, or declaring itself harvested without naming a source, is half-declared in a way no control can catch. Declared symmetrically, provenance also makes a harvester specifiable from the model itself rather than from a side document.
**Why.** A term of the vocabulary is declared, always and by definition; recording that on every term would repeat one fact a hundred times and say nothing. It is the INSTANCES that have a provenance, and the class is where the model states which one: a governance object is asserted by a domain, a physical column is harvested from a system. The distinction matters because a class can be declared and describe captured things at once — CapturedObject itself is a declared term naming harvested instances, and conflating the two is what once put a harvesting mode on an abstraction. Nothing is inherited. A subclass declares its own mode rather than taking its parent's, so that the declaration is read where the instances are typed and not chased up a chain. The agreement clause is what keeps that free of contradiction: the axis says what kind of thing the class describes, the mode says how those things arrive, and a class under CapturedObject declaring ASSERTED is stating both at once. Declared this way, provenance also makes a harvester specifiable from the model itself rather than from a side document.
| From | To | Note |
|---|---|---|
| harvestSource present | authoringMode HARVESTED | |
| authoringMode on an abstract class | nothing | an abstraction has no instances to produce |
| a class under CapturedObject declaring ASSERTED | violation | the mode contradicts the axis |
| authoringMode HARVESTED, harvestSource absent | harvestSource declared | |
## TN-027 — A concrete class has one layer and one provenance
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long