ontology-validator — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited ontology-validator (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Validate that material sample annotations comply with ontology constraints: correct class names, valid properties, consistent domain/range relationships, and required fields present.
cmso_summary.json and ontology_registry.json| Input | Description | Example |
|---|---|---|
| Annotation | JSON dict or list of annotation dicts | {"class":"UnitCell","properties":{"has Bravais lattice":"cF"}} |
| Class name | Class to check completeness for | Crystal Structure |
| Provided properties | Comma-separated property names | "has unit cell,has space group" |
| Relationships | JSON array of subject-property-object triples | [{"subject_class":"Material","property":"has structure","object_class":"Crystal Structure"}] |
What do you need to validate?
├── An annotation (classes and properties are correct)
│ └── schema_checker.py --ontology cmso --annotation '<json>'
├── Completeness of a class annotation
│ └── completeness_checker.py --ontology cmso --class <name> --provided <props>
└── Object property relationships
└── relationship_checker.py --ontology cmso --relationships '<json>'| Script | Key Outputs |
|---|---|
scripts/schema_checker.py | results.valid, results.errors (each unknown_class/unknown_property error carries a suggestions array of nearest matches), results.warnings, results.class_valid, results.properties_valid |
scripts/completeness_checker.py | results.completeness_score, results.required_missing, results.recommended_missing, results.optional_missing, results.unrecognized |
scripts/relationship_checker.py | results.valid, results.results, results.errors |
schema_checker.py to verify correctness.completeness_checker.py to see what required/recommended properties are missing.relationship_checker.py to ensure domain/range consistency.User: I annotated my sample as CrystalStructure with properties hasUnitCell and hasBasis.
Is this correct and complete?
Agent: Let me both validate the annotation and check its completeness.
[Runs: schema_checker.py --ontology cmso --annotation
'{"class":"Crystal Structure","properties":{"has unit cell":true,"has basis":true}}' --json]
[Runs: completeness_checker.py --ontology cmso --class "Crystal Structure"
--provided "has unit cell,has basis" --json]
From schema_checker.py (results.warnings):
- has unit cell: valid for Crystal Structure
- has basis: domain_mismatch warning — its domain is "Unit Cell", not
Crystal Structure (so this property belongs on the Unit Cell instance)
From completeness_checker.py (results, completeness_score = 0.5):
- **required_missing**: has space group
So: add "has space group" to the Crystal Structure annotation, and move
"has basis" onto the Unit Cell annotation. (The domain insight comes from
schema_checker.py's warnings; completeness_checker.py only reports the
missing required "has space group".)# Validate an annotation
python3 skills/ontology/ontology-validator/scripts/schema_checker.py \
--ontology cmso \
--annotation '{"class":"Unit Cell","properties":{"has Bravais lattice":"cF"}}' \
--json
# Check completeness
python3 skills/ontology/ontology-validator/scripts/completeness_checker.py \
--ontology cmso \
--class "Crystal Structure" \
--provided "has unit cell,has space group" \
--json
# Validate relationships
python3 skills/ontology/ontology-validator/scripts/relationship_checker.py \
--ontology cmso \
--relationships '[{"subject_class":"Computational Sample","property":"has material","object_class":"Material"}]' \
--json| Error | Cause | Resolution |
|---|---|---|
Class 'X' not found ... (did you mean 'Y'?) | Invalid/misspelled class name | Apply the nearest-match suggestions from the error, or use ontology-explorer to find the correct name |
Property 'X' not found ... (did you mean 'Y'?) | Invalid/misspelled property name | Apply the nearest-match suggestions from the error, or use property_lookup.py to search |
Annotation must be a dict | Wrong input format | Provide valid JSON dict |
Relationships must be a non-empty list | Wrong input format | Provide JSON array of relationship dicts |
properties. It weights required, recommended, and optional properties equally, so a moderate score (e.g. 0.5-0.67) can coexist with missing required properties. ALWAYS check required_missing first: a non-empty required_missing means the annotation is invalid regardless of the score.
schema_checker.py --json and recorded results.valid; confirmed results.errors is an empty array (a valid:true with any unknown_class/unknown_property error cannot occur, but confirm the array length is 0 rather than trusting the boolean alone).domain_mismatch entry in results.warnings, recorded the property, its reported domain, and the class it was applied to, then made an explicit keep-or-move decision (warnings are not auto-fixed and may be intentional for a subclass).completeness_checker.py --json and confirmed results.required_missing is empty BEFORE quoting completeness_score — a non-empty required_missing means the annotation is invalid no matter how high the score is.completeness_score together with the required_missing, recommended_missing, and optional_missing lists (do not paraphrase the score as "complete" while any required item is missing).suggestions[0] value and confirmed the corrected name actually exists in the ontology (re-ran the checker, or checked via ontology-explorer) rather than assuming the top suggestion is right.relationship_checker.py --json for every subject-property-object triple and confirmed each per-triple results.results[i].valid is true; recorded any results.errors strings naming the offending domain or range.--ontology used (e.g. cmso, asmo) matches the ontology the annotation was authored against — a class can be "unknown" simply because the wrong constraints/summary file was loaded.| Tempting shortcut | Why it's wrong / what to do |
|---|---|
| "completeness_score is 0.67, so the annotation is basically complete." | The score weights required, recommended, and optional tiers equally, so a high score can still hide a missing required property. Check required_missing first; a non-empty list means invalid regardless of score. |
| "schema_checker returned only warnings, no errors, so I'll ignore them." | domain_mismatch warnings flag a property attached to a class that is not (a subclass of) its domain — often the property belongs on a different instance. Record each warning and decide explicitly; don't auto-dismiss. |
| "The class name didn't match but the validator gave a suggestion, so I'll just use it." | suggestions come from stdlib difflib fuzzy matching (cutoff 0.6) and can be wrong or empty. Verify the suggested name exists in the ontology before applying it. |
| "Two of the three relationships passed, so the triples are fine." | results.valid is the AND over all triples; you must inspect each results.results[i] and its errors. A single failing domain/range check invalidates the relationship set. |
| "It returned valid:true, so the annotation is semantically correct." | The checker only verifies class/property existence and domain/range against a manually curated constraints file. It does not check data types, cardinality, or value plausibility — valid:true is necessary, not sufficient. |
| "Property exists in the ontology, so it applies to my class." | Existence is checked against the full property set; domain applicability is a separate subclass-aware check. A real property can still trigger a domain_mismatch warning on the wrong class. |
| "I'll trust the bare class name; substrings are close enough." | Domain/subclass matching is exact-equality plus parent traversal, NOT substring containment. Material is not credited with Crystalline Material properties; use the precise ontology class name. |
--ontology is validated against registered ontology names in ontology_registry.json (fixed allowlist)--annotation JSON is parsed with json.loads() and validated as a dict with required class and properties keys--class names are validated against known classes in the ontology summary; unknown classes produce clear errors--provided property names are validated as comma-separated strings and matched against known properties--relationships JSON is parsed and validated as a non-empty list of dicts, each requiring subject_class, property, and object_class keysreferences/ directory: ontology_registry.json, cmso_summary.json, cmso_constraints.json (all read-only)schema_checker.py, completeness_checker.py, relationship_checker.py) with explicit argument listseval(), exec(), or dynamic code generationshell=True)json.loads() only (no pickle, no YAML with unsafe loaders)| Date | Version | Changes |
|---|---|---|
| 2026-06-23 | 1.2.0 | Subclass-aware domain matching (fixes substring false positives/negatives), nearest-match suggestions on unknown class/property, input size/length caps, eval and doc corrections |
| 2026-02-25 | 1.0 | Initial release with CMSO validation support |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.