Ontology SKOS Audit
Structural integrity audit for SKOS concept schemes. Uses rdflib to parse any RDF serialization (Turtle, OWL, RDF/XML, N-Triples, JSON-LD, etc.) and navigate the SKOS graph to detect 8 categories of structural issues.
What It Detects
| Check | Severity | Description |
|---|---|---|
inScheme-undefined |
❌ Error | skos:inScheme references a ConceptScheme that is never defined in the repo |
no-inScheme |
⚠️ Warning | Concept has no skos:inScheme — orphaned from any ConceptScheme |
empty-scheme |
⚠️ Warning | ConceptScheme has no concepts |
missing-prefLabel |
❌ Error | Concept has no skos:prefLabel (required by SKOS) |
duplicate-prefLabel |
❌ Error | Two concepts in the same scheme have identical prefLabel + lang |
notation-mismatch |
ℹ️ Info | skos:notation value doesn't match the URI fragment or any prefLabel |
broader-no-inScheme |
⚠️ Warning | Concept has skos:broader but no skos:inScheme |
broken-broader |
❌ Error | skos:broader target is not defined as a skos:Concept |
broken-narrower |
❌ Error | skos:narrower target is not defined as a skos:Concept |
Setup
Create a virtual environment and install dependencies:
cd <your-ontology-repo>
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install rdflib
After finishing: deactivate the venv and remove it:
deactivate && rm -rf .venvSkip this if the user asks to keep the environment.
Workflow
1. Run the audit
python scripts/skos_audit.py . -o SKOS_REPORT.md
2. JSON output for CI pipelines
python scripts/skos_audit.py . -o skos_issues.json --format json
Example JSON entry:
{
"severity": "error",
"check": "inScheme-undefined",
"message": "Concept :StreetLamp references undefined ConceptScheme ex:MissingScheme",
"subject_short": ":StreetLamp",
"scheme_short": "ex:MissingScheme"
}
How It Works
┌─────────────────────┐
│ RDF files in repo │
│ (.ttl, .owl, .rdf, │
│ .nt, .jsonld, …) │
└────────┬────────────┘
│ rdflib parses all into one graph
▼
┌─────────────────────┐
│ skos_audit.py │
│ SPARQL-like graph │
│ traversal: │
│ skos:Concept │
│ skos:ConceptScheme│
│ skos:inScheme │
│ skos:broader │
│ skos:narrower │
│ skos:prefLabel │
│ skos:notation │
└────────┬────────────┘
▼
SKOS_REPORT.md
(or .json)
Standardized Report
All skills support --format report which outputs a common JSON schema:
{
"skill": "skill-name",
"summary": {"errors": N, "warnings": N, "info": N},
"issues": [{"file": ".ttl", "element": ":Class", "message": "...",
"severity": "error|warning|info", "check": "RULE",
"suggestion": "fix"}]
}
This format is consumed by ontology-full-audit to produce unified reports.
Output Files
Never write files into the repository without permission. Before generating
any report or output file, ask the user where to save it (e.g. -o ../report.md
or an absolute path outside the repo). The default output path in script
examples is only a suggestion — always confirm with the user first.
Important Rules
missing-prefLabelis always an error. SKOS requiresskos:prefLabelon everyskos:Concept. A concept with onlyskos:altLabelis not valid.duplicate-prefLabelwithin a scheme is almost always wrong. Two concepts in the same scheme should not share the same label sinceprefLabelis meant to be unique per language.notation-mismatchis informational, not always wrong. The script normalizes accents and spaces before comparing. A mismatch may be intentional (e.g. legacy notation) — review manually.empty-schememay be intentional if the scheme is defined in a different file not scanned. Adjust the repo path accordingly.For SKOS,
skos:notationuses unaccented forms. e.g.pista-de-padel, whileskos:prefLabeluses proper orthography:Pista de Pádel.
Troubleshooting
| Problem | Solution |
|---|---|
| "No RDF files found" | The script skips hidden dirs (.git, .venv, etc.). Ensure your SKOS files are in a non-excluded directory. |
| Empty report when issues exist | Check that the SKOS files use correct namespace prefixes (rdflib requires prefix declarations in each file). |
Compact_uri shows full URIs instead of prefix:name |
Add @prefix declarations to your SKOS files for cleaner output. |