An ODRL 2.2 profile with deterministic evaluation semantics for data governance.
Adalbert is a proper ODRL 2.2 profile. It uses ODRL terms for all standard constructs (Permission, Duty, Prohibition, Agreement, etc.) and only adds extensions where ODRL 2.2 leaves behavior undefined:
- Explicit lifecycle: Pending → Active → Fulfilled/Violated (unified for duties and contracts)
- Bilateral agreements: Both assigner and assignee may have duties
- Deterministic evaluation: Total functions, no undefined states
- Formal verification target: Amenable to Dafny, Why3, Coq
- Structured operand resolution:
resolutionPathfrom canonical roots (agent, asset, context) - Recurring duties:
recurrencevia RFC 5545 RRULE for scheduled obligations
Adalbert is specification-first. The semantics document defines what any conformant implementation must do. Every Adalbert policy is a valid ODRL 2.2 policy.
See examples/ for complete working policies:
- data-contract.ttl — DataContract, Subscription, bilateral duties
- data-use-policy.ttl — Role-based access, purpose constraints
| Extension | ODRL 2.2 | What Adalbert Adds |
|---|---|---|
| Duty lifecycle | Undefined | Pending → Active → Fulfilled/Violated |
| Bilateral duties | Unilateral (assignee only) | Assigner duties + assignee duties |
| Conflict resolution | Configurable | Fixed: Prohibition > Permission |
| Evaluation order | Undefined | Deterministic left-to-right |
| Operand resolution | Implicit | Explicit resolutionPath from canonical roots |
| Recurring duties | — | recurrence via RFC 5545 RRULE with per-instance deadline |
| Contract types | — | DataContract (subclass of Offer), Subscription (subclass of Agreement) |
Note: Adalbert is an ODRL profile, not a parallel vocabulary. Standard ODRL processors can parse Adalbert policies; Adalbert-aware processors additionally enforce lifecycle, bilateral duties, and deterministic evaluation.
The formal semantics is the normative reference.
Every evaluation terminates with a defined result:
Eval : Request × PolicySet × State → Decision × DutySet
Agreements return duties for both parties:
Result = {
decision: Permit | Deny | NotApplicable,
assignerDuties: Set<Duty>, // Provider obligations (SLAs)
assigneeDuties: Set<Duty>, // Consumer obligations
violations: Set<Duty>
}
Duties and contracts share four states:
condition true
Pending ──────────────> Active
│ │
action done │ │ deadline passed
▼ ▼
Fulfilled Violated
An odrl:Duty progresses through adalbert:State values. An adalbert:DataContract shares the same state machine.
Operands resolve via resolutionPath — dot-separated paths from canonical roots:
agent.role, agent.organization, agent.costCenter
asset.classification, asset.market, asset.isBenchmark
context.purpose, context.environment, context.legalBasis
Adalbert/
├── config/
│ └── namespaces.ttl # Authoritative namespace registry
├── ontology/
│ ├── adalbert-core.ttl # ODRL profile extension
│ ├── adalbert-shacl.ttl # Validation shapes
│ ├── adalbert-prof.ttl # DXPROF profile declaration
├── profiles/
│ └── adalbert-due.ttl # Data use vocabulary (all operands + actions)
├── examples/
│ ├── data-contract.ttl # Complete contract example (with recurrence)
│ ├── data-use-policy.ttl # Access control example
│ └── baseline.ttl # Comprehensive test data (8 contracts, 2 subscriptions)
└── docs/
├── adalbert-overview.md # What is Adalbert? (start here)
├── adalbert-specification.md # Technical vocabulary reference
├── adalbert-term-mapping.md # Business term -> property mapping + DCON migration
├── Adalbert_Semantics.md # Formal semantics (normative)
├── contracts-guide.md # Data contract authoring guide
├── policy-writers-guide.md # Data use policy authoring guide
└── comparisons/
└── comparison-dcon.md # DCON supersession analysis
As of v0.7, Adalbert supersedes DCON. DCON's promise hierarchy dissolves into standard odrl:Duty patterns with DUE actions (deliver, notify, conformTo, report). Recurring obligations use adalbert:recurrence (RFC 5545 RRULE) instead of DCON's scheduling constraints.
| DCON | Adalbert v0.7 | Status |
|---|---|---|
dcon:DataContract |
adalbert:DataContract |
Absorbed into core |
dcon:DataContractSubscription |
adalbert:Subscription |
Absorbed into core |
dcon:Promise hierarchy |
odrl:Duty + DUE actions |
Dissolved |
dcon:promisedDeliveryTime |
adalbert:recurrence + adalbert:deadline |
Scheduling + window |
See comparison-dcon.md for the supersession analysis, adalbert-term-mapping.md for complete DCON -> Adalbert property mapping, and contracts-guide.md for the contracts authoring guide.
Promise terminology. If you prefer DCON-style "promise" naming (ProviderPromise, QualityPromise, etc.), this can be reintroduced as syntactic sugar. A promise is a Duty where
adalbert:subjectequals the policy'sodrl:assigner. Two options: (1) LinkML authoring sugar — apromiseclass that expands to a standard Duty, no ontology change; (2) OWL thin alias —adalbert:Promise rdfs:subClassOf odrl:Dutywith a SHACL constraint, making promises queryable in SPARQL. See issues.md Q1 for details.
| Prefix | Namespace | Role |
|---|---|---|
odrl: |
http://www.w3.org/ns/odrl/2/ |
Primary — all standard constructs |
adalbert: |
https://vocabulary.bigbank/adalbert/ |
Extensions only (State, deadline, recurrence, DataContract, Subscription, resolutionPath, hierarchy) |
adalbert-due: |
https://vocabulary.bigbank/adalbert/due/ |
Data use vocabulary (operands, domain-specific actions, concept values); ODRL Common Vocabulary actions used directly |
An implementation conforms to Adalbert if:
- It accepts policies that validate against
adalbert-shacl.ttl - It uses
odrl:Permission,odrl:Duty,odrl:Prohibition,odrl:Agreementfor standard constructs - Its evaluation function produces identical results for identical inputs
- All functions are total (no undefined behavior)
- State transitions match the operational semantics
- Agreement evaluation returns duties for both assigner and assignee
Version: 0.7 | Date: 2026-02-04