Skip to content

Commit 8058dbd

Browse files
turbomamclaude
andcommitted
docs: add synonym + identifier-scheme guidelines; note typed owl:deprecated
Durable contributor guidelines (conventions, not todos) capturing decisions made during release prep: - docs/synonym-conventions.md — the two kinds of synonym column (ontology-native exact/related vs source-bound), the reified `>AI IAO:0000119` source-provenance pattern, and the rules: keep source values verbatim, source-bound duplicates across classes are intentional (cross-system value mapping, do not de-dup), exact synonyms should be near-unique (overload tracked in #444). - docs/identifier-scheme.md — canonical w3id IRIs, the `https://w3id.org/metpo/` resolvable base (nothing above it resolves), no obolibrary PURLs, resolution behavior, and where the IRI values are configured (odk.yaml, not the generated Makefile; ODK/w3id mismatch tracked in #465). - docs/deprecation-workflow.md — corrected the deprecated.tsv directive example to the typed `AT owl:deprecated^^xsd:boolean` and explained why (the #467 fix). Docs only; no ontology or code changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 541991d commit 8058dbd

3 files changed

Lines changed: 165 additions & 4 deletions

File tree

docs/deprecation-workflow.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,21 @@ by editing the upstream Google Sheet and running `make download-sheets`.
5757
The file is a ROBOT template. Column layout:
5858

5959
```
60-
ID label TYPE deprecated obsolescence reason
61-
ID LABEL TYPE A owl:deprecated AI IAO:0000231
62-
METPO:XXXXXXX obsolete <former label> owl:Class true OMO:0001000
60+
ID label TYPE deprecated obsolescence reason
61+
ID LABEL TYPE AT owl:deprecated^^xsd:boolean AI IAO:0000231
62+
METPO:XXXXXXX obsolete <former label> owl:Class true OMO:0001000
6363
```
6464

6565
Add one row per deprecated term. Use:
6666
- **label**: `obsolete ` + the former rdfs:label (e.g. `obsolete lyses`)
6767
- **TYPE**: `owl:Class` for classes, `owl:ObjectProperty` / `owl:DataProperty` /
6868
`owl:AnnotationProperty` for properties
69-
- **deprecated**: always `true`
69+
- **deprecated**: always `true`. The directive **must be typed** as
70+
`AT owl:deprecated^^xsd:boolean`. A bare `A owl:deprecated` emits an *untyped* literal
71+
(`<owl:deprecated>true</owl:deprecated>`), which ROBOT/OWL API do not recognize as a
72+
deprecation — that previously caused ~4000 spurious default-profile report findings
73+
(deprecated terms not excluded from `missing_definition`/`duplicate_label`, plus
74+
`deprecated_boolean_datatype` and `misused_obsolete_label`). Fixed in #467; keep it typed.
7075
- **obsolescence reason**: use `OMO:0001000` (out of scope) or `IAO:0000226`
7176
(placeholder removed) — see the existing rows for precedent. When in doubt, use
7277
`IAO:0000226`.

docs/identifier-scheme.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# METPO Identifier and IRI Scheme
2+
3+
**Purpose:** The canonical form of METPO identifiers and ontology IRIs, how they resolve,
4+
and where the values are configured. Follow this when minting terms, building releases,
5+
or editing ODK configuration.
6+
7+
---
8+
9+
## The Short Version
10+
11+
- **Term IRIs** are `https://w3id.org/metpo/<7-digit id>` (prefix `METPO:`
12+
`https://w3id.org/metpo/`). Classes are `METPO:1xxxxxx`, properties `METPO:2xxxxxx`.
13+
- **`https://w3id.org/metpo/` is the canonical, resolvable base.** w3id delegates only the
14+
`/metpo/` path, so *everything* — terms, the ontology document, version IRIs, and
15+
release products — must live under it.
16+
- **METPO does not use `purl.obolibrary.org` PURLs.** METPO is not registered in the OBO
17+
Foundry, so `http://purl.obolibrary.org/obo/METPO_<id>` returns HTTP 404. Do not mint,
18+
advertise, or filter on obolibrary IRIs.
19+
20+
---
21+
22+
## Canonical IRIs
23+
24+
| Thing | IRI |
25+
|---|---|
26+
| Term (class/property) | `https://w3id.org/metpo/<id>` |
27+
| Main ontology document | `https://w3id.org/metpo/metpo.owl` |
28+
| Version IRI | `https://w3id.org/metpo/releases/<date>/metpo.owl` |
29+
| Products (`-base`, `-full`) | `https://w3id.org/metpo/metpo-base.owl`, `…/metpo-full.owl` |
30+
31+
All of these are under `https://w3id.org/metpo/`. An IRI **above** that path (e.g.
32+
`https://w3id.org/metpo.owl`) is **not resolvable** — it falls outside w3id's `/metpo/`
33+
delegation and 404s — so it must never be used as the ontology IRI.
34+
35+
## Resolution
36+
37+
The `/metpo/` catch-all in [`perma-id/w3id.org`](https://github.com/perma-id/w3id.org)
38+
redirects `https://w3id.org/metpo/*`:
39+
40+
- `https://w3id.org/metpo/metpo.owl` → the raw release OWL on GitHub.
41+
- `https://w3id.org/metpo/<id>` → the BioPortal class page. This works in **browsers**
42+
(BioPortal sits behind a Cloudflare bot challenge that only blocks non-browser clients;
43+
human resolution is the design goal). Machine/linked-data dereferenceability would come
44+
from OLS once METPO is loaded there (see #213).
45+
46+
## Where the values are configured
47+
48+
The IRI base lives in **`src/ontology/metpo-odk.yaml`** (`uribase`) and flows into the
49+
**generated** `src/ontology/Makefile` as `URIBASE` / `ONTBASE` and the report/base-artifact
50+
`--base-iri`. The correct values for the scheme above are:
51+
52+
```
53+
URIBASE = https://w3id.org/metpo
54+
ONTBASE = https://w3id.org/metpo
55+
--base-iri = $(URIBASE) # i.e. https://w3id.org/metpo, which matches term IRIs
56+
```
57+
58+
**Do not hand-edit `src/ontology/Makefile`.** It is ODK-generated ("DO NOT EDIT THIS
59+
FILE"); `make update_repo` regenerates it and would overwrite manual edits. Configure the
60+
scheme in `metpo-odk.yaml` and regenerate. Note that ODK's IRI machinery is OBO-PURL
61+
oriented (it assumes `<base>/ONT_<id>` underscore terms and a registry-root ontology IRI),
62+
which does not map cleanly onto METPO's w3id slash scheme; reconciling this is tracked in
63+
**#465** (the ODK upgrade). Vestiges such as a `$(URIBASE)/METPO_` base-IRI in the report
64+
recipe come from that mismatch and match no real METPO term.
65+
66+
See also: `docs/synonym-conventions.md`, `docs/deprecation-workflow.md`, and the
67+
"Identifiers and resolution" section of the top-level `README.md`.

docs/synonym-conventions.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# METPO Synonym Conventions
2+
3+
**Purpose:** How METPO records synonyms, which annotation property each Google-Sheet
4+
column maps to, and the rules a curator (or an automated check) must follow. The
5+
classes tab has two *kinds* of synonym column with different rules.
6+
7+
---
8+
9+
## The Short Version
10+
11+
- **Ontology-native** synonyms are clean, curated US English that METPO asserts in its
12+
own voice. They use `oboInOwl:hasExactSynonym` / `hasRelatedSynonym` with no source.
13+
- **Source-bound** synonyms are **verbatim** strings from an external database, paired
14+
with a source column that **reifies** the synonym assertion with its provenance.
15+
- **Never normalize a source-bound value**, and **never de-duplicate source-bound
16+
synonyms across classes** — both are intentional (see below).
17+
- An **exact** synonym should (almost) uniquely identify one class. The same exact
18+
synonym on many classes is an *overload* and is discouraged.
19+
20+
---
21+
22+
## The columns and their ROBOT directives
23+
24+
| Column | Directive | Property | Kind |
25+
|---|---|---|---|
26+
| `confirmed exact synonym` | `A oboInOwl:hasExactSynonym SPLIT=\|` | exact synonym | ontology-native |
27+
| `literature mining related synonyms` | `A oboInOwl:hasRelatedSynonym SPLIT=\|` | related synonym | ontology-native |
28+
| `madin synonym or field` | `A oboInOwl:hasRelatedSynonym SPLIT=\|` | related synonym | source-bound |
29+
| `Madin synonym source` | `>AI IAO:0000119 SPLIT=\|` | (axiom annotation) | source provenance |
30+
| `bacdive keyword synonym` | `A oboInOwl:hasRelatedSynonym SPLIT=\|` | related synonym | source-bound |
31+
| `Bacdive synonym source` | `>AI IAO:0000119` | (axiom annotation) | source provenance |
32+
| `bactotraits related synonym` | `A oboInOwl:hasRelatedSynonym SPLIT=\|` | related synonym | source-bound |
33+
| `Bactotraits synonym source` | `>AI IAO:0000119` | (axiom annotation) | source provenance |
34+
| `metatraits synonym` | `A oboInOwl:hasRelatedSynonym SPLIT=\|` | related synonym | source-bound |
35+
| `MetaTraits synonym source` | `>AI IAO:0000119` | (axiom annotation) | source provenance |
36+
37+
The leading `>` on each `*source*` column is a ROBOT template directive that **annotates
38+
the preceding synonym assertion** rather than the term. The result is a reified
39+
synonym, e.g. in the OWL:
40+
41+
```xml
42+
<owl:Axiom>
43+
<owl:annotatedSource rdf:resource="https://w3id.org/metpo/2000002"/>
44+
<owl:annotatedProperty rdf:resource="…oboInOwl#hasRelatedSynonym"/>
45+
<owl:annotatedTarget>assimilation</owl:annotatedTarget>
46+
<obo:IAO_0000119 rdf:resource="https://bacdive.dsmz.de/"/>
47+
</owl:Axiom>
48+
```
49+
50+
This is how METPO records **which external-system value maps to which METPO entity**:
51+
the synonym is the verbatim external value and the `IAO:0000119` (definition source)
52+
annotation records the database it came from.
53+
54+
---
55+
56+
## Rules
57+
58+
1. **Source-bound columns hold verbatim source strings.** Do not "correct" them, even
59+
when the source has typos, odd casing, inconsistent prefixes, or non-English forms.
60+
Downstream consumers (e.g. the kg-microbe transformers) match on the exact source
61+
string; normalizing breaks the match.
62+
2. **Duplicate source-bound related synonyms across classes are intentional.** One
63+
external value (e.g. a BactoTraits temperature bin code) legitimately maps to several
64+
METPO classes; keeping it on each — each reified with its source — is the point. Do
65+
**not** treat these as duplicates to remove. (A `duplicate_*_synonym` QC finding on a
66+
`hasRelatedSynonym` is expected for source-bound values.)
67+
3. **Ontology-native columns use clean, consistent US English.** Foreign-language forms,
68+
source typos, and one-off transcriptions belong in source-bound columns, not here.
69+
4. **Exact synonyms should be near-unique.** `oboInOwl:hasExactSynonym` asserts the value
70+
*is* a name for the class, so the same exact synonym on many sibling classes is an
71+
*overload* (a qualitative term like `mesophilic` stamped onto every numeric bin). Pick
72+
one canonical owner; downgrade the others to `hasRelatedSynonym` or drop them. Tracked
73+
in issue #444.
74+
5. **If a source value also happens to be the desired ontology-native synonym, put it in
75+
both columns** — do not rely on a source-bound column to carry English semantics.
76+
77+
---
78+
79+
## Why reification (not bare synonyms)
80+
81+
A bare synonym says "this string names this class." METPO additionally needs to say
82+
"this string is *the value used by database X*," so that the same human-facing concept
83+
can be mapped to multiple external vocabularies and back. The reified `IAO:0000119`
84+
provenance is what makes the synonym a *mapping record*, not just a label. (This is
85+
distinct from the observation-reification layer that was removed in #371; synonym-source
86+
reification is a deliberate, retained feature.)
87+
88+
See also: `docs/deprecation-workflow.md`, `docs/identifier-scheme.md`, and the
89+
"Synonym Column Conventions" section of the repository `CLAUDE.md`.

0 commit comments

Comments
 (0)