Skip to content

Commit 12e5db6

Browse files
committed
feat(lance-graph-ontology): seed NamespaceRegistry with bO-* upstream vocabs
Companion to PR #407 (merged). Expands `NamespaceRegistry::seed_defaults` from 16 to 29 entries, registering the 13 external vocabularies that PR #407 added hydrators for. This is the O(1) IRI ↔ context_id matching table backed by `lance_cache.rs`'s Lance dataset; consumers like smb-office-rs and woa-rs lookup by namespace shortname instead of hand-rolling slot constants. Why this lives in lance-graph-ontology, not in OGIT: - Public OWL/RDF source files stay pristine in data/ontologies/ (DOLCE+DUL, FIBO-FND/BE, OWL-Time, PROV-O, QUDT, schema.org, SKOS, ZUGFeRD CII XSDs + Schematron). Modifying them taints downstream use. - The OGIT repo is authoritative for namespace registrations but adding new TTL files there with hand-picked contextIds would be drift. - The matching table belongs in the CLIENT (lance-graph-ontology), keyed by namespace shortname, persisted via the existing lance_cache layer. - Per user direction 2026-05-21: "expand always but drift is probably bad" + "deinterlace them locally and keep that matching table in a lance table for O(1) and check what lance-graph-ontology has in regards" → expansion lives here, OGIT untouched. Allocation: ID Namespace PR / Hydrator ───────────────────────────────────────────────────────── 0 SMB (pre-existing) 1 WorkOrder (pre-existing) 2 Healthcare (pre-existing) 3 Network (pre-existing) 4 EmailCorrespondance (pre-existing) 5 SharePoint (pre-existing) 10-19 Medical/<sub> (pre-existing, dense) 20 Foundation/DOLCE-DUL bO-1 hydrate_dolce 21 Foundation/OWL-Time bO-2 hydrate_owltime 22 Foundation/PROV-O bO-3 hydrate_provo 23 Foundation/QUDT bO-4 hydrate_qudt 24 Foundation/schema-org bO-8 hydrate_schemaorg 25 Foundation/SKOS bO-5 hydrate_skos 30 FinancialAccounting/FIBO-FND bO-6 hydrate_fibo_fnd 31 FinancialAccounting/FIBO-BE bO-7 hydrate_fibo_be 32 FinancialAccounting/ZUGFeRD bO-16 hydrate_zugferd 33 FinancialAccounting/ZUGFeRD-Rules bO-15 hydrate_zugferd_rules 34 FinancialAccounting/SKR03 bO-13 hydrate_skr03 35 FinancialAccounting/SKR04 bO-13 hydrate_skr04 36 FinancialAccounting/SKR03-Bau bO-13 hydrate_skr03_bau Allocation policy matches the existing Medical/<sub> pattern: dense within family-range, gaps between ranges left as expansion room. `allocate()` continues to fill gaps 6..=9 and 26..=29 first, then 37+. Notes: - `next_free_id` doc-comment updated to reflect the new seed layout. First dynamic id is now 6 (was already 6 in practice; the prior comment said "20" which was off by 14). - Three regression tests updated: * `seed_defaults_has_sixteen_entries` → `_has_twenty_nine_entries` * `seed_defaults_assigns_canonical_ids` adds spot-checks at 20/25/30/34/35/36 * `allocate_skips_to_first_unused_id` len assertion 16 → 29 - One integration test (`tests/context_id_test.rs`) updated to match. All 116 lance-graph-ontology tests pass; clippy clean (5 pre-existing oxrdf deprecation warnings, no new); downstream consumers (callcenter, consumer-conformance, cognitive-shader-driver) build clean.
1 parent 2e3dd48 commit 12e5db6

2 files changed

Lines changed: 62 additions & 11 deletions

File tree

crates/lance-graph-ontology/src/namespace_registry.rs

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl NamespaceRegistry {
8787
/// - `lance-graph-callcenter::hydration::parse_super_domain_name`
8888
/// - OQ-4 resolution in PR #366 / EPIPHANIES 2026-05-13 sprint-7 meta entry
8989
pub fn seed_defaults() -> Self {
90-
let mut ids = HashMap::with_capacity(16);
90+
let mut ids = HashMap::with_capacity(29);
9191
// Live cognitive namespaces.
9292
ids.insert("SMB".to_string(), 0); // export-only per v5 ratification
9393
ids.insert("WorkOrder".to_string(), 1);
@@ -108,6 +108,26 @@ impl NamespaceRegistry {
108108
ids.insert("Medical/HPO".to_string(), 17);
109109
ids.insert("Medical/DRON".to_string(), 18);
110110
ids.insert("Medical/CHEBI".to_string(), 19);
111+
// Foundation/<vocab> reserved range 20..=29 (PR-bO-1..bO-5, bO-8).
112+
// L1 upper ontology + L2 utility vocabularies hydrated by
113+
// lance-graph-ontology::hydrators. Public OWL/RDF sources kept
114+
// pristine in data/ontologies/; this registry is the local
115+
// IRI ↔ context_id matching table (O(1) via lance_cache).
116+
ids.insert("Foundation/DOLCE-DUL".to_string(), 20);
117+
ids.insert("Foundation/OWL-Time".to_string(), 21);
118+
ids.insert("Foundation/PROV-O".to_string(), 22);
119+
ids.insert("Foundation/QUDT".to_string(), 23);
120+
ids.insert("Foundation/schema-org".to_string(), 24);
121+
ids.insert("Foundation/SKOS".to_string(), 25);
122+
// FinancialAccounting/<vocab> reserved range 30..=39
123+
// (PR-bO-6, bO-7, bO-13, bO-15, bO-16).
124+
ids.insert("FinancialAccounting/FIBO-FND".to_string(), 30);
125+
ids.insert("FinancialAccounting/FIBO-BE".to_string(), 31);
126+
ids.insert("FinancialAccounting/ZUGFeRD".to_string(), 32);
127+
ids.insert("FinancialAccounting/ZUGFeRD-Rules".to_string(), 33);
128+
ids.insert("FinancialAccounting/SKR03".to_string(), 34);
129+
ids.insert("FinancialAccounting/SKR04".to_string(), 35);
130+
ids.insert("FinancialAccounting/SKR03-Bau".to_string(), 36);
111131
Self { ids }
112132
}
113133

@@ -147,9 +167,12 @@ impl NamespaceRegistry {
147167
self.ids.iter().map(|(k, v)| (k.as_str(), *v))
148168
}
149169

150-
/// First context id that is not currently in use. Skips the seed ranges
151-
/// to keep allocations dense within their family (v1 ids 0..=3 + 10..=19
152-
/// occupied by `seed_defaults`; first dynamic id therefore lands at 20).
170+
/// First context id that is not currently in use. Walks `0u32..` and
171+
/// returns the first value not present in the registry. With the
172+
/// current `seed_defaults` (16 cognitive + 13 Foundation/FinancialAccounting
173+
/// entries), the seed occupies 0..=5 + 10..=19 + 20..=25 + 30..=36;
174+
/// the first dynamic id therefore lands at 6 (next gap), then 7..=9,
175+
/// then 26..=29, then 37+. Allocation stays dense across seed gaps.
153176
fn next_free_id(&self) -> u32 {
154177
let mut candidate: u32 = 0;
155178
let used: std::collections::BTreeSet<u32> = self.ids.values().copied().collect();
@@ -165,9 +188,15 @@ mod tests {
165188
use super::*;
166189

167190
#[test]
168-
fn seed_defaults_has_sixteen_entries() {
191+
fn seed_defaults_has_twenty_nine_entries() {
169192
let r = NamespaceRegistry::seed_defaults();
170-
assert_eq!(r.len(), 16);
193+
// 6 cognitive (SMB, WorkOrder, Healthcare, Network, Email, SharePoint)
194+
// + 10 Medical/* (ICD10CM..CHEBI)
195+
// + 6 Foundation/* (DOLCE-DUL, OWL-Time, PROV-O, QUDT, schema-org, SKOS)
196+
// + 7 FinancialAccounting/* (FIBO-FND, FIBO-BE, ZUGFeRD, ZUGFeRD-Rules,
197+
// SKR03, SKR04, SKR03-Bau)
198+
// = 29
199+
assert_eq!(r.len(), 29);
171200
}
172201

173202
#[test]
@@ -183,17 +212,26 @@ mod tests {
183212
// Medical/<sub> reserved range 10..=19.
184213
assert_eq!(r.get("Medical/ICD10CM"), Some(10));
185214
assert_eq!(r.get("Medical/CHEBI"), Some(19));
215+
// Foundation/<vocab> reserved range 20..=29.
216+
assert_eq!(r.get("Foundation/DOLCE-DUL"), Some(20));
217+
assert_eq!(r.get("Foundation/OWL-Time"), Some(21));
218+
assert_eq!(r.get("Foundation/SKOS"), Some(25));
219+
// FinancialAccounting/<vocab> reserved range 30..=39.
220+
assert_eq!(r.get("FinancialAccounting/FIBO-FND"), Some(30));
221+
assert_eq!(r.get("FinancialAccounting/SKR03"), Some(34));
222+
assert_eq!(r.get("FinancialAccounting/SKR04"), Some(35));
223+
assert_eq!(r.get("FinancialAccounting/SKR03-Bau"), Some(36));
186224
}
187225

188226
#[test]
189227
fn allocate_skips_to_first_unused_id() {
190228
let mut r = NamespaceRegistry::seed_defaults();
191-
// 0..=5 and 10..=19 are taken; first free id is 6.
229+
// Occupied: 0..=5, 10..=19, 20..=25, 30..=36. First free id is 6.
192230
let id = r.allocate("CallCenter");
193231
assert_eq!(id, 6);
194232
// Idempotent: re-allocate returns the same id.
195233
assert_eq!(r.allocate("CallCenter"), 6);
196-
// Next allocation skips again.
234+
// Next allocation skips again (still in 6..=9 gap).
197235
assert_eq!(r.allocate("Splat"), 7);
198236
}
199237

crates/lance-graph-ontology/tests/context_id_test.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,20 @@ fn namespace_registry_seed_defaults_assigns_canonical_v1_ids() {
6464
assert_eq!(r.get("Medical/DRON"), Some(18));
6565
assert_eq!(r.get("Medical/CHEBI"), Some(19));
6666

67-
// 16 seed mappings total (6 cognitive + 10 medical).
68-
assert_eq!(r.len(), 16);
67+
// Foundation reserved range 20..=29 (PR-bO-1..bO-5, bO-8).
68+
assert_eq!(r.get("Foundation/DOLCE-DUL"), Some(20));
69+
assert_eq!(r.get("Foundation/SKOS"), Some(25));
70+
71+
// FinancialAccounting reserved range 30..=39 (PR-bO-6, bO-7, bO-13, bO-15, bO-16).
72+
assert_eq!(r.get("FinancialAccounting/FIBO-FND"), Some(30));
73+
assert_eq!(r.get("FinancialAccounting/SKR03-Bau"), Some(36));
74+
75+
// 29 seed mappings total:
76+
// 6 cognitive (SMB / WorkOrder / Healthcare / Network / Email / SharePoint)
77+
// + 10 medical (ICD10CM..CHEBI)
78+
// + 6 foundation (DOLCE-DUL, OWL-Time, PROV-O, QUDT, schema-org, SKOS)
79+
// + 7 financial (FIBO-FND, FIBO-BE, ZUGFeRD, ZUGFeRD-Rules, SKR03, SKR04, SKR03-Bau)
80+
assert_eq!(r.len(), 29);
6981
}
7082

7183
#[test]
@@ -88,7 +100,8 @@ fn namespace_registry_allocate_is_idempotent_and_dense() {
88100
let id2 = r.allocate("Splat");
89101
assert_eq!(id2, 7);
90102
assert_ne!(id1, id2);
91-
assert_eq!(r.len(), 18);
103+
// Seed (29) + 2 new allocations = 31.
104+
assert_eq!(r.len(), 31);
92105
}
93106

94107
#[test]

0 commit comments

Comments
 (0)