Domains & Entities
The Problem
To evaluate expectations, WRIT needs a structured vocabulary — what kinds of things exist, what properties they have, and how they relate to each other. Without this, an expectation like "all IT services must have an owner" has no way to know what an IT service is, what "owner" means, or where to find the data.
How WRIT Handles It
WRIT organises this vocabulary into a domain — a complete knowledge base consisting of entity types, entity sets, attributes, relationships, and data sources.
Entity Types
An entity type defines a kind of thing and its properties. Think of it as a schema or class definition:
entity type: "ITService"
display name: "IT Service"
display format: "{name}"
unknown if missing: "owner_email"
void if missing: "name"
exhaustive: true
from: "services_data"
identifying attributes: "name"
Key fields:
| Field | Purpose |
|---|---|
unknown if missing |
These attributes return Unknown when their data is absent. Generates questions. |
void if missing |
These attributes return Void when absent. A structural impossibility — no questions generated. |
exhaustive |
Whether this is a complete list. If true, a missing entity means it does not exist (Void). If false, it might exist elsewhere (Unknown). |
from |
The attestation source providing data for this entity type. |
Entity Sets
An entity set is a collection of entity instances loaded from data. You declare them in the DSL:
entity set: "all_it_services"
of: "ITService"
The set is populated at evaluation time from the attestation source declared in the entity type.
Exhaustive vs Partial Sets
This is one of WRIT's most important distinctions:
| Property | Exhaustive Set | Partial Set |
|---|---|---|
| Missing entity lookup | Returns Void | Returns Unknown |
| Meaning | "This entity definitely does not exist" | "This entity might exist but we do not have its data" |
| Questions generated? | No — structural impossibility | Yes — data might be obtainable |
Example: If your department list is exhaustive and an employee references "Marketing" which is not in the list, that is Void — Marketing does not exist as a department. But if the list is partial, the same lookup returns Unknown — Marketing might exist, we just do not have it.
Attributes
Attributes are properties of entity types, linked to data fields:
attribute: "owner_email"
of: "ITService"
from data field: "owner_email"
match on: "name"
type: string
unknowns: "N/A", ""
voids: "__EMPTY__"
trues: "__EMPTY__"
falses: "__EMPTY__"
validity: 365 days
The unknowns and voids fields define sentinel values — specific CSV values that should be treated as Unknown or Void rather than as real data.
Relationships
Relationships connect entity types via attribute matching:
relationship: "owner"
of: "ITService"
from: "owner_email"
to: "all_people" of "Person"
match on: "email"
When you traverse a relationship (e.g. looking up the owner of a service), the result depends on whether the target set is exhaustive or partial:
- Exhaustive target, match found — Returns the matched entity.
- Exhaustive target, no match — Returns Void (the entity definitely does not exist).
- Partial target, no match — Returns Unknown (the entity might exist elsewhere).
Worked Example
A simple domain with IT services and people:
entity type: "ITService"
display name: "IT Service"
display format: "{name}"
unknown if missing: "owner_email"
void if missing: "name"
exhaustive: true
from: "services_data"
identifying attributes: "name"
entity type: "Person"
display name: "Person"
display format: "{name}"
unknown if missing: "__EMPTY__"
void if missing: "name", "email"
exhaustive: false
from: "people_data"
identifying attributes: "email"
entity set: "all_it_services"
of: "ITService"
entity set: "all_people"
of: "Person"
relationship: "owner"
of: "ITService"
from: "owner_email"
to: "all_people" of "Person"
match on: "email"
Common Pitfalls
- Wrong exhaustive flag — Marking a partial data source as exhaustive means missing entities are treated as non-existent (Void) instead of unknown. This suppresses questions that should be asked.
- Missing sentinel values — If your CSV uses "N/A" for missing data but you do not list it in
unknowns, WRIT treats "N/A" as a real value. - Forgetting identifying attributes — These are used to match entities across data sources. Getting them wrong means data does not link up correctly.
What to Read Next
- Three-Valued Logic — How WRIT evaluates incomplete data.
- Domain Modelling — Complete guide to building domain models.
- Glossary — Entity type, entity set, exhaustive, partial definitions.
WRIT Docs