# Ontology Skos Audit

> Provides a script and instructions to audit SKOS concept schemes for structural integrity — inScheme references, prefLabels, duplicates, notations, and hierarchy links. Use when validating SKOS thesauri, taxonomies, or concept schemes before release.

- Skill: `daniel-dona/ontology-skos-audit` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add daniel-dona/ontology-skos-audit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/daniel-dona/ontology-skos-audit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- License: MIT
- Author: daniel-dona (https://skillmd.com/u/daniel-dona)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/daniel-dona/ontology-skos-audit

---


# 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:

```bash
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:
> ```bash
> deactivate && rm -rf .venv
> ```
> Skip this if the user asks to keep the environment.

## Workflow

### 1. Run the audit

```bash
python scripts/skos_audit.py . -o SKOS_REPORT.md
```

### 2. JSON output for CI pipelines

```bash
python scripts/skos_audit.py . -o skos_issues.json --format json
```

Example JSON entry:

```json
{
  "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:
```json
{
  "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

1. **`missing-prefLabel` is always an error.** SKOS requires `skos:prefLabel`
   on every `skos:Concept`. A concept with only `skos:altLabel` is not valid.

2. **`duplicate-prefLabel` within a scheme is almost always wrong.** Two
   concepts in the same scheme should not share the same label since
   `prefLabel` is meant to be unique per language.

3. **`notation-mismatch` is informational, not always wrong.** The script
   normalizes accents and spaces before comparing. A mismatch may be
   intentional (e.g. legacy notation) — review manually.

4. **`empty-scheme` may be intentional** if the scheme is defined in a
   different file not scanned. Adjust the repo path accordingly.

5. **For SKOS, `skos:notation` uses unaccented forms.** e.g.
   `pista-de-padel`, while `skos:prefLabel` uses 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. |

