Competency-question annotation vocabulary

The tool-internal annotation vocabulary Protégé MCP uses when a competency question travels inside the ontology artifact.

  • Namespace IRI: https://hakjuoh.github.io/protege-mcp/cq#
  • Suggested prefix: cq
  • Machine-readable: cq.ttl (Turtle)

Table of contents

  1. Why a tool namespace
  2. competencyQuestion
    1. Example
  3. Stability

Why a tool namespace

Competency questions managed by the add_competency_question / run_competency_questions tools are stored in one of three conventions. Two are files next to the ontology document (robot-sparql-dir, the default writer, and sidecar-manifest); the third — ontology-annotations — stores each CQ inside the ontology itself as an ontology-level annotation, and is the fallback writer when the ontology has no saved document to place a file next to.

That annotation property is plugin bookkeeping, not a project term, so it is minted in this namespace — one the plugin controls — rather than in your ontology’s namespace. A fixed, global IRI is what lets any Protégé MCP instance (or any other tool aware of this vocabulary) rediscover the CQs in an artifact regardless of the ontology’s own IRI, and it keeps the plugin from injecting terms into your terminological space. For the same reason, entities under https://hakjuoh.github.io/protege-mcp/ are exempt from validate_ontology / validate_governance owned-term audits.

This is a hash namespace: this page is the namespace document, and each term is a fragment of it. GitHub Pages cannot content-negotiate, so the HTML lives at the namespace IRI and the Turtle is published alongside as cq.ttl.


competencyQuestion

https://hakjuoh.github.io/protege-mcp/cq#competencyQuestion

An owl:AnnotationProperty. Each ontology-level annotation under this property holds one competency question, serialised as a JSON object in an xsd:string literal — the same JSON shape a sidecar-manifest entry uses:

Field Type Required Meaning
id string yes Stable id within this store (e.g. CQ-1). Not globally unique.
text string no The natural-language competency question.
type string no Optional category, e.g. Scoping | Validating.
query_lang string no Defaults to sparql (the only supported value; a DL path is reserved).
query string yes Executable SPARQL 1.1 SELECT or ASK.
include_inferred boolean no Run over inferred triples too (default true).
expected object no Pass condition (default {"kind":"nonEmpty"}), one of: {"kind":"nonEmpty"}, {"kind":"empty"}, {"kind":"count","op":">=","value":N} (op>=, <=, ==, >, <), {"kind":"exactRows","rows":[…]}. exactRows compares an order- and duplicate-insensitive row set; use query-level aggregation when multiplicity matters. On load a compact string is also accepted ("nonEmpty" | "empty" | "count >= 3"); the plugin always writes the object form.
tags array no Free-form tags.

An annotation whose literal does not parse as a JSON object describing a valid CQ — a non-empty id, a query, a supported query_lang, a well-formed expected — is skipped on load (reported under skipped, never fatal) — see list_competency_questions.

Example

An ontology carrying one CQ under this convention:

@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix cq:  <https://hakjuoh.github.io/protege-mcp/cq#> .

<http://example.org/onto> a owl:Ontology ;
    cq:competencyQuestion """{"id":"CQ-1","text":"Does every process have a participant?","query_lang":"sparql","query":"SELECT ?p WHERE { ?p a <http://example.org/onto#Process> . FILTER NOT EXISTS { ?p <http://example.org/onto#hasParticipant> ?x } }","include_inferred":true,"expected":{"kind":"empty"}}""" .

Writes are ordinary undoable ontology changes (one transaction per CQ upsert), gated by the same write-consent preference as every other write tool.


Stability

The property IRI and the JSON field set above are a public contract from the moment they are written into an artifact: existing fields are never repurposed, and additions stay backwards-compatible. Fields this vocabulary does not define are ignored on load — and dropped when the plugin rewrites the annotation — so do not park third-party data inside the literal.


Protégé MCP is licensed under the BSD 2-Clause License. Protégé is a trademark of Stanford University.

This site uses Just the Docs, a documentation theme for Jekyll.