Skip to content

Document what Ubergraph's SPARQL results actually contain#899

Open
gaurav wants to merge 2 commits into
mainfrom
docs-ubergraph-curie-validation
Open

Document what Ubergraph's SPARQL results actually contain#899
gaurav wants to merge 2 commits into
mainfrom
docs-ubergraph-curie-validation

Conversation

@gaurav

@gaurav gaurav commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Documentation only — no code changes, no effect on any build.

src/datahandlers/obo.py filters Ubergraph results three times over with

prefix in ["http", "ro"] or prefix.startswith("t") or "#" in prefix

Nothing explained what each clause was for. Working that out against the 2026-06-30 download turned up that the check is also wrong, so this PR records the findings rather than leaving them in a comment thread. The fix itself is deliberately deferred to #898, because getting the exclusion list wrong either admits bad identifiers or silently drops good ones from the next build.

What the investigation found

The four clauses look like four instances of one check. They are two different kinds of check wearing one coat:

  • Syntactic — "is this even a CURIE?" (http, t…, #), a property of the Ubergraph/SPARQL boundary.
  • Policy — "do we want this vocabulary?" (ro is the Relation Ontology: predicates, not entities), which belongs in config.yaml next to ubergraph_ontologies — a list that already contains RO.

Because a policy exclusion was smuggled into a syntax check, the syntax half went unexamined. Measured leaks in babel_downloads/common/ubergraph/labels:

Leak Rows Why
https://purl.brain-bican.org/…, ORCIDs, Wikidata, SSSOM 8,762 the filter tests "http", not "https"
RO:0002213 "positively regulates" and ~770 others 772 it tests lowercase "ro"; opt_to_curie() emits RO
OBO:REL#:part:of 1 the # lands in the local part, not the prefix

synonyms.jsonl leaks 1,331 https: rows the same way. These are harmless today only because NodeFactory looks labels up by CURIE and no compendium carries an https or RO prefix — they cost memory, not correctness. That is luck: TCDB is the only real prefix starting with t and it survives only because it is uppercase.

Two details worth having written down: UberGraph.is_blank_node() already exists and is stricter than startswith("t"), but is only used to decide whether to warn, so the blank node still flows out as a raw string and forces obo.py to filter again. And the # garbage is manufactured by Text.opt_to_curie(), which splits OBO PURLs on / then _ without validating the result — not by Ubergraph or by RDF.

Naming

docs/sources/README.md said "one directory per data source, named by the source's CURIE prefix", which has no answer for Ubergraph: it is a merged triplestore serving identifiers from ~200 prefixes and owns none of them. The second commit reserves the all-caps directory name for real CURIE prefixes — so an all-caps name always means "you can look this prefix up" — and spells other sources in their own capitalisation.

Companion to #898, which carries the proposed design, the test plan, and the open research questions (notably: those 6,895 https://purl.brain-bican.org/taxonomy/… rows are real, labelled BICAN cell-type identifiers, and whether to drop or properly CURIE-ify them should be a choice rather than a side effect of a string comparison).

🤖 Generated with Claude Code

gaurav and others added 2 commits July 9, 2026 02:06
src/datahandlers/obo.py filters Ubergraph results three times over with

    prefix in ["http", "ro"] or prefix.startswith("t") or "#" in prefix

but nothing explained what each clause was for, and the check turns out to
be wrong. Record the findings against the 2026-06-30 download:

- bare IRIs reach obo.py because ubergraph.py falls back to the raw IRI
  when Text.opt_to_curie() raises;
- blank nodes are `t` + digits, already recognised precisely by the
  existing UberGraph.is_blank_node();
- Text.opt_to_curie() manufactures invalid CURIEs (`core#part:of`) from
  fragment IRIs, which is where the "#" clause comes from;
- "ro" is a policy exclusion (RO is predicates, not entities), not a
  syntax check -- and it is the reason the syntax half went unexamined.

Measured leaks: 8,762 `https:` rows (the filter tests "http"), 772 `RO:`
rows (it tests lowercase "ro"), and one `OBO:REL#:part:of` (the "#" lands
in the local part). Harmless today only because NodeFactory looks labels
up by CURIE and no compendium carries those prefixes.

Tracked in #898.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs/sources/README.md said "one directory per data source, named by the
source's CURIE prefix", which has no answer for Ubergraph: it is a merged
triplestore serving identifiers from ~200 prefixes and owns none of them.

Reserve the all-caps directory name for real CURIE prefixes, so that an
all-caps name always means "you can look this prefix up", and spell other
sources in their own capitalisation (Ubergraph/, not UBERGRAPH/).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant