Overlay Profile Mechanism
Context
PDTF v3 is a base transaction plus a family of form overlays (BASPI4/5, TA6/7/10, NTS/NTS2/NTSL, CON29R/DW, LLC1, LPE1, FME1, …) composed at runtime by getTransactionSchema’s deep-merge. Each overlay unions required arrays, unions enum member lists, and carries per-leaf form-question references (baspi5Ref, ntsRef — e.g. BASPI B1.3.2). Overlays also encode oneOf discriminated unions — most sharply participants.items discriminated on role, with a nested sellersCapacity oneOf (Legal-Owner/Mortgagee vs Personal-Representative/Attorney, the latter requiring sellersCapacityDetails and attachments).
A class per overlay (baspi:PropertyPack, ta6:PropertyPack) was rejected unanimously in Session 001 (Q3, Q5): that nesting is form ergonomics, not ontology. Overlays are views over a fixed TBox — they constrain, they do not declare. The question (Q5, owned by Knublauch): how do we re-express overlays so loading a form’s requirements activates the right constraints and can re-generate the form, without (a) misusing SHACL so a profile validates the wrong thing, (b) leaking closed-world shape semantics into the open-world class model, (c) letting an overlay touch a Kind’s identity, or (d) promoting a build-config artefact to ontological status with no fixed model theory.
The BASPI5 slice is the MVP: its discriminated oneOf/sellersCapacity structure stresses every hard construct (sh:xone, merged sh:in, DASH editors, dct:source), so if it round-trips — JSON → profile → rendered form + validated transaction — the remaining overlays are largely mechanical.
Decision
Overlays are named, dereferenceable SHACL profile graphs over a fixed TBox; composition is a documented build-step graph-union; conditional requirement is reified as a first-class opda:ValidationContext; DASH drives form rendering; dct:source carries traceability to form questions. This is the only option that keeps the class model fixed and open-world while making each form’s requirements an activatable, checkable, re-generable view — and the two reservations that could have sunk it (Guarino’s “no fixed model theory” and Cagle’s advisory-annotation push) were resolved by reification and graph-separation.
Rules
Knublauch’s canonical mapping (core unanimous, 12-0):
- required-array union →
sh:minCount 1. Eachrequiredentry becomes a property shape withsh:minCount 1on the target node shape (e.g. baspi5’srequired: ["uprn", "address", …]onpropertyPack→sh:property [ sh:path opda:uprn ; sh:minCount 1 ]shapes onopda:PropertyPack, active only when BASPI5 is loaded). On graph union this is purely additive — no conflict to resolve. - enum union → a single merged
sh:in. A JSONenum→sh:in ( … ). The effectivesh:inis the set-union of base plus every loaded profile’s members. This is a build-step replacement, not an entailment: at build time you replace thesh:innode with the union list. You do not leave twosh:inconstraints on one property — twosh:ins are conjunctive (intersection), the opposite of the union intent. Loaded profile = active vocabulary. oneOf→sh:xone.oneOfis exactly-one, so the strictly-correct construct issh:xone(reservesh:orfor “at least one”). baspi5’sparticipants.itemsdiscriminated onrole→ a node shapesh:xone ( [non-seller] [seller] ), with the discriminator expressed viash:qualifiedValueShapekeyed on therole/sellersCapacityvalue. The nestedsellersCapacityoneOf→ a nestedsh:xonewhose Personal-Representative/Attorney branch carries the extrash:minCount 1shapes forsellersCapacityDetailsandattachments.- per-leaf
baspi5Ref/ntsRef→dct:source. Each annotated shape getsdct:source(withrdfs:isDefinedBywhere appropriate) pointing at a minted, dereferenceable form-question IRI — e.g.<https://opda.uk/forms/baspi5#B1.3.2>— forming a shape → question → form chain. SSSOM is the richer alternative, deferred per Q2 (Cagle dissent recorded). - DASH for rendering. Per property shape:
dash:propertyRole dash:KeyRoleon UPRN,dash:LabelRoleon name leaves;dash:viewer(dash:LabelViewer/dash:LiteralViewerfor reads,dash:URIViewerfordct:sourcelinks);dash:editor(dash:EnumSelectEditorfor role/capacity enums driven bysh:in,dash:TextFieldEditorforsellersCapacityDetails,dash:DetailsEditorfor nestedaddress);sh:order+sh:groupreproduce the form’s field order and sectioning. Loading the BASPI5 profile yields a graph that both validates a transaction and generates the BASPI form with fulldct:sourcetraceability — the canonical round-trip.
opda:ValidationContext reification (Guarino’s accepted withdrawal condition). A profile is reified as a first-class opda:ValidationContext node. A sh:minCount 1 is a constraint of a named context — “required under the Conveyancer profile” — not a free-floating axiom whose truth is a function of which files a build call passed. This converts conditionality from “required (depending)” into “required relative to a named, dereferenceable context”, giving the fixed model theory the Devil’s Advocate demanded.
No-identity-override gate (Guizzardi). A SHACL gate rejects any overlay that declares or overrides a Kind’s identity or key. A profile may add presence and vocabulary constraints; it may never restate or alter the identity criterion or key mechanism settled in ODR-0005. Identity belongs to the rigid Kind, not to a form context. (Structural check on the profile graphs themselves → ODR-0013.)
Graph separation (Q3). Class graph and shapes graph remain separate files. Shapes target classes via sh:targetClass/sh:targetNode/sh:targetObjectsOf — a shape with no target validates nothing. Shapes reference classes via targeting, never owl:imports. sh:minCount 1 is not owl:minCardinality — open-world OWL/RDFS must not be confused with closed-world SHACL.
Advisory annotations exiled to a separate graph (≈7-2). Advisory LLM-consumer annotations (opda:aiHint) do not live inside the shapes graph; they live in a separate annotation graph keyed to shape IRIs (→ ODR-0013). A SHACL processor must find only interpretable constraint components plus known annotation properties (sh:, dash:, rdfs:, dct:); a constraint-adjacent invented term risks being read as a constraint.
Enforcement (round-trip on the BASPI5 slice). Loading the profile must (a) validate a conformant transaction, (b) report violations on a non-conformant one (e.g. a Seller acting as Attorney with no sellersCapacityDetails/attachments), and (c) re-generate the BASPI form via the DASH annotations with every field carrying a resolvable dct:source. A build-step test asserts the composed profile’s effective sh:in is the set-union (not the intersection) of base and loaded members — the regression guard against stacked sh:in. Profile and form-question URIs MUST dereference (…/profiles/baspi5/ returns a working shapes graph; …/forms/baspi5#B1.3.2 resolves). Demonstrated 2026-06-01 (ODR-0003 termination signal 1 / plan B2): ci-baspi5-roundtrip exercises (a)+(b) end-to-end over conformant + non-conformant transaction exemplars (the non-conformant case is the Seller-as-Power-of-Attorney with no opda:hasEvidencedAuthority, whose violation traces via sh:sourceShape → dct:source → …/forms/baspi5#B1.3.2), and (c) as a data-contract check (31/31 property shapes carry a resolvable dct:source + DASH render hints) — the DASH-UI render itself is the consumer-app boundary. Validator-capability note: the sellersCapacity sh:xone (Rule 3) requires a SHACL-AF-capable validator (pyshacl advanced=True); a SHACL-Core-only processor passes the xone-of-property-shapes vacuously. A conformant-Legal-Owner exemplar guards the vacuous-pass direction.
Overlay Profile Layering Mechanism
The flowchart below shows how a form overlay is loaded, composed with the base schema at build time, and then used to both validate a transaction and re-generate a form — the canonical round-trip described in the Decision section.
(fixed, open-world)"]:::process OVL["Overlay profile graph
(e.g. baspi5.ttl)"]:::process GATE{"No-identity-override
gate (ODR-0013)"}:::warning REJECT["Rejected —
overlay touches Kind identity"]:::warning VC["opda:ValidationContext
(reified named context)"]:::process COMPOSE["Build-step graph-union
(sh:minCount, sh:in, sh:xone,
dct:source, DASH annotations)"]:::warning SHAPES["Composed shapes graph
(profile-scoped SHACL)"]:::success VALIDATE["Validate transaction
(conformant / violations)"]:::success RENDER["Re-generate form
(DASH viewer/editor + dct:source)"]:::success BASE --> GATE OVL --> GATE GATE -->|"overlay safe"| VC GATE -->|"identity overridden"| REJECT VC --> COMPOSE COMPOSE --> SHAPES SHAPES --> VALIDATE SHAPES --> RENDER
Overlay Composition Build-Step Rules
The three union/replacement rules from the Decision section determine how each overlay’s constructs are merged into the base shapes at build time.
(property shape)"]:::success ENUM["enum member list"]:::process -->|"set-union → replace"| SHIN["merged sh:in
(single list, not stacked)"]:::success ONEOF["oneOf discriminator"]:::process -->|"→ exactly-one"| XONE["sh:xone
(nested for sellersCapacity)"]:::success LEAFREF["baspi5Ref / ntsRef"]:::process -->|"→ traceability"| DCT["dct:source
(dereferenceable form-question IRI)"]:::success FIELDMETA["field order / section"]:::process -->|"→ rendering"| DASH["sh:order + sh:group
+ dash:editor / dash:viewer"]:::success
Options Considered and Decision Reached
The three alternatives evaluated by the council, with the reasons for acceptance or rejection as stated in the Alternatives section.
(baspi:PropertyPack, ta6:PropertyPack…)"]:::process OPT2["Option B: SHACL profile graphs
over fixed TBox"]:::process OPT3["Option C: Inline advisory annotations
in shapes graph"]:::process D1{"Q3/Q5: Form ergonomics
vs ontology?"}:::warning D2{"Fixed model theory +
graph separation?"}:::warning D3{"SHACL processor
purity?"}:::warning REJ1["Rejected unanimously (Q3)
— declares, not constrains;
identity drift risk"]:::error CHOSEN["CHOSEN: Named, dereferenceable
SHACL profile graphs;
opda:ValidationContext reification;
DASH rendering; dct:source traceability"]:::success REJ3["Rejected (≈7-2)
— shapes graph polluted;
naïve consumer may read
aiHint as constraint"]:::error ANN["Advisory annotations → separate
annotation graph (→ ODR-0013)"]:::success OPT1 --> D1 D1 -->|"no — UI contract ≠ semantics"| REJ1 OPT2 --> D2 D2 -->|"yes — reification + graph-separation
resolves Guarino + Cagle reservations"| CHOSEN OPT3 --> D3 D3 -->|"no — strict processor risk"| REJ3 REJ3 --> ANN
ODR Dependency Graph
This ODR’s depends-on and implements relationships from the frontmatter, showing how it sits within the broader ontology programme.
PDTF ontology programme"]:::user ODR0004["ODR-0004
PDTF ontology foundation"]:::process ODR0005["ODR-0005
Property/land identity"]:::process ODR0006["ODR-0006
Agents and roles"]:::process ODR0007["ODR-0007"]:::process ODR0009["ODR-0009"]:::process ODR0011["ODR-0011
Enumeration vocabularies"]:::process ODR0013["ODR-0013
SHACL validation + severity"]:::process ODR0017["ODR-0017"]:::user THIS["ODR-0010
Overlay profile mechanism"]:::success ODR0004 -->|"depends-on"| THIS ODR0005 -->|"depends-on"| THIS ODR0006 -->|"depends-on"| THIS ODR0007 -->|"depends-on"| THIS ODR0009 -->|"depends-on"| THIS ODR0011 -->|"depends-on"| THIS ODR0013 -->|"depends-on"| THIS THIS -->|"implements"| ODR0003 THIS -->|"implements"| ODR0017
Alternatives
- A class per overlay (
baspi:PropertyPack,ta6:PropertyPack, …) — rejected unanimously (Q3): recreates form ergonomics as an OWL class hierarchy, conflating UI contract with semantics, and overlays would declare rather than constrain, multiplying near-duplicate classes and inviting identity drift across them (Guizzardi’s gate forbids it). - Inline advisory annotations in the shapes graph — rejected (≈7-2): a shapes graph polluted with
opda:aiHintis no longer cleanly a SHACL graph; a strict processor carries triples it cannot interpret and a naïve consumer may read them as constraints. The need is real and met by a separate annotation graph keyed to shape IRIs.
Consequences
- The TBox stays fixed and open-world; each form’s requirements become an activatable, checkable view; the UI/requirement contract can evolve without touching the class model.
- Composition is a build-step graph-union that MUST be specified and maintained as code (mirroring
getTransactionSchema’s deep-merge). “Loaded = active” is documentation-and-tooling, not entailment — a tool that gets the merge wrong (stackingsh:in) is silently incorrect with no reasoner to catch it. - Deliverables to produce:
profiles/baspi5.ttl(worked MVP slice); theopda:ValidationContextpattern; the no-identity-override SHACL gate; the composition build-step specification mirroringgetTransactionSchema; the separate advisory-annotation graph keyed to shape IRIs (→ ODR-0013). - The
dct:sourcefallback is reasoner-poorer than SSSOM for per-leaf mappings (no machine-readable justification/confidence) — a known trade accepted by deferring SSSOM. - Enum members are owned by ODR-0011 (SKOS); annotation-graph and severity tiering by ODR-0013. This record fixes the profile mechanism and delegates vocabulary fill and validation severities.
References
- Target versions: RDF 1.2 and SHACL 1.2, per the Core-tier pin in ODR-0002.
- Vocabularies: SHACL (profile shapes); DASH (form rendering —
dash:propertyRole/viewer/editor,sh:order/sh:group); Core (dct:source/rdfs:isDefinedBytraceability); SKOS for enum members surfaced viash:in(→ ODR-0011); localopda:ValidationContextreifying the profile. SSSOM deferred (Q2; Cagle dissent recorded). - Source schema & composition: overlays under
source/03-standards/schemas/src/schemas/v3/overlays/and the deep-merge ingetTransactionSchema(web appsrc/pages/implementation/schema-composition.astro). The business glossary notespropertyPackappears in 18 overlays andaddress/attachments/ownershipin ~10 each — the spanning leaves a profile composition must reconcile. - Related: anchor ODR-0003; foundation and graph separation ODR-0004; the identity crux whose keys an overlay may not touch ODR-0005; Seller/Buyer roles and
sellersCapacitythe BASPI discriminator constrains ODR-0006; enumeration members surfaced viash:inODR-0011; SHACL severity, no-identity-override gate, annotation-graph split ODR-0013; catalogue ODR-0014. - Council deliberation: session-001 Q5 (owned by Knublauch); rule-by-rule mapping in
working/shacl-trio.md. Ratified by session-010 (Reduced Council, 2026-05-27; Queen Knublauch; DA Guarino — 7 conceded / 1 withdrew on Q1 UFO Substance Kind §Rules amendment). Q1 5-propertyopda:ValidationContextreification + UFO Substance Kind commitment discharging S001 Q5 concession fully. Q6 no-identity-override SHACL meta-shape atsh:Violation— ODR-0017 11th citing site triggered §2a amendment (landed inline at S013). Q7 BASPI5 round-trip as MVP gate. Q8 three-rule interface contract with ODR-0013 (cross-cite per Cagle Scope-Check 1 Q6 amendment). - Three-rule interface contract with ODR-0013 (operationalising Cagle Scope-Check 1 Q6 amendment; reciprocal cross-cite per S013 Q7):
sh:insemantics — merged at build time per §1a Rule 2 (build-step replacement, NOT entailment).sh:Violationfloor — ODR-0013 §Rules.Q1 OWNS the floor; this ODR (§Q6 no-identity-override) INHERITS and ENFORCES at the profile-layer.- No-identity-override gate — ODR-0013 OWNS the identity-key list (from ODR-0005); this ODR (§Q6) ENFORCES via SHACL meta-shape
opda:ProfileIdentityOverrideCheckRuleatsh:Violationper ODR-0017 §2a amendment.
Comments