Skip to content

indexed and RDFLib class-detail paths diverge for predicates outside ANNOTATION_PROPERTIES #212

Description

@damienriehl

Surfaced while fixing the class-save data loss (CatholicOS/ontokit-web#361). Not the data-loss bug itself — that one is being fixed separately — but the same family, and worth recording rather than leaving as folklore.

The divergence

get_class_detail has two implementations:

  • indexed (ontokit/services/ontology_index.py) returns whatever the indexer captured, so it surfaces any annotation predicate present on the class.
  • RDFLib fallback (ontokit/services/ontology.py, _class_to_response) iterates the fixed ANNOTATION_PROPERTIES allowlist.

The allowlist is narrower. Verified: skos:related (and by the same logic skos:broader, skos:narrower, and anything else outside the dict) is not in ANNOTATION_PROPERTIES. So for a class carrying skos:related, the indexed path returns it and the fallback does not.

The same class returns a different predicate set depending on whether the index happens to be warm.

How it surfaced

The parity test added alongside the #361 fix originally included skos:related in its fixture and failed on exactly this. The implementing worker removed that triple as an "invalid fixture assumption" — a defensible call to keep the fix focused, and it reported the removal honestly rather than hiding it. But the underlying inconsistency is real and is now untested.

Severity: lower than it looks, but non-zero

The web-side fix for #361 makes updateClassInTurtle round-trip safe, so a predicate missing from the API response is no longer destroyed on save — it is merely invisible in the editor. That downgrades this from data loss to a display/consistency gap.

It still matters because:

  • the response is non-deterministic from the client's perspective — same class, different answer depending on index warmth;
  • it is the identical shape as the #361 root cause: two code paths that are supposed to agree, silently disagreeing, with the discrepancy only appearing under real-world conditions;
  • any future consumer that trusts the annotation set (export, diff, validation, translation coverage) inherits the inconsistency.

Suggested direction

Pick one and make it explicit:

  1. Widen the fallback to return all annotation predicates rather than an allowlist, matching the indexed path; or
  2. Narrow the indexed path to the same allowlist, if the allowlist is a deliberate product decision about what counts as an annotation.

Either way, derive both paths from one definition so they cannot drift, and restore skos:related to the parity fixture so the guarantee is tested.

Option 1 is likely correct — an allowlist that silently hides predicates present in the user's ontology is surprising, especially for a tool whose job is round-tripping OWL.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions