Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions crates/lance-graph-ogar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ serde = ["ogar-vocab/serde", "ogar-adapter-surrealql/serde"]
# folds ogar-class-view's transitive git contract onto it = ONE source.
lance-graph-contract = { path = "../lance-graph-contract" }

# OGIT spine (the NamespaceBridge trait + registry + namespace/error types the
# OGAR-driven port bridges build on). The OGIT/OGAR seam: the bridges live HERE
# (OGAR) because they couple to ogar-vocab; the trait + registry they implement
# against live in lance-graph-ontology (OGIT). OGIT does NOT depend on OGAR.
lance-graph-ontology = { path = "../lance-graph-ontology" }

# ── OGAR Active-Record forks: git deps @ main (the canonical superset; matches
# symbiont's pins so they resolve to ONE source in the golden image) ──
ogar-vocab = { git = "https://github.com/AdaWorldAPI/OGAR", branch = "main" }
Expand All @@ -89,3 +95,8 @@ ogar-adapter-surrealql = { git = "https://github.com/AdaWorldAPI/OGAR", branch =
# the patch (see the CONSUMER REQUIREMENT note in the header).
[patch."https://github.com/AdaWorldAPI/lance-graph"]
lance-graph-contract = { path = "../lance-graph-contract" }

[dev-dependencies]
# TTL fixtures for the moved bridge scope-lock / codebook-convergence tests
# stage on-disk via tempfile::tempdir() + std::fs (matches lance-graph-ontology).
tempfile = "3"
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ mod tests {
//! Healthcare fixtures differ.

use super::*;
use crate::bridge::{BridgeError, NamespaceBridge};
use crate::error::Error;
use crate::namespace::NamespaceId;
use crate::namespace_registry::NamespaceRegistry;
use crate::registry::OntologyRegistry;
use lance_graph_ontology::bridge::{BridgeError, NamespaceBridge};
use lance_graph_ontology::error::Error;
use lance_graph_ontology::namespace::NamespaceId;
use lance_graph_ontology::namespace_registry::NamespaceRegistry;
use lance_graph_ontology::registry::OntologyRegistry;
use ogar_vocab::class_ids;
// PortSpec needed in scope for `HealthcarePort::aliases()`.
use ogar_vocab::ports::PortSpec;
Expand Down
58 changes: 58 additions & 0 deletions crates/lance-graph-ogar/src/bridges/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! OGAR-driven tenant port bridges.
//!
//! This is the OGAR side of the OGIT/OGAR separation (operator,
//! 2026-06-20). These bridges couple to `ogar_vocab::ports` /
//! `ogar_vocab::class_ids` (the OGAR codebook + `PortSpec` class schema),
//! so they live here in `lance-graph-ogar`, NOT in `lance-graph-ontology`
//! (which is OGIT and must not depend on `ogar-vocab`). The OGIT-side
//! legacy bridges (`WoaBridge` / `SpearBridge` / `SharePointBridge` /
//! `OgitBridge`) stay in `lance_graph_ontology::bridges`.
//!
//! # Two layers
//!
//! - The **generic harness** [`unified::UnifiedBridge<P: PortSpec>`] is the
//! one-and-only `lance_graph_ontology::NamespaceBridge` impl for
//! OGAR-driven ports. It inherits everything that varies between ports
//! (`NAMESPACE` / `BRIDGE_ID` / public-name → class_id aliases) from
//! `ogar_vocab::ports::PortSpec`. Adding a port is `impl PortSpec for
//! FooPort {…}` in OGAR — no bridge boilerplate here.
//! - The **per-port aliases** ([`OpenProjectBridge`], [`RedmineBridge`],
//! [`MedcareBridge`]) are thin `type` aliases over the harness.
//!
//! # OGAR-driven ports (`UnifiedBridge<P>` aliases)
//!
//! - [`OpenProjectBridge`]: `UnifiedBridge<ogar_vocab::ports::OpenProjectPort>`
//! — locks to the `OpenProject` namespace. `WorkPackage` / `TimeEntry`
//! / `Project` etc. resolve to OGAR canonical class_ids via the
//! port's alias table.
//! - [`RedmineBridge`]: `UnifiedBridge<ogar_vocab::ports::RedminePort>` —
//! locks to the `Redmine` namespace. `Issue` / `TimeEntry` / `Project`
//! etc. resolve to the SAME OGAR canonical class_ids as the
//! OpenProject equivalents, so cross-fork convergence is the default
//! not the exception.
//! - [`MedcareBridge`]: `UnifiedBridge<ogar_vocab::ports::HealthcarePort>`
//! — locks to the `Healthcare` namespace. `Patient` / `Diagnosis` /
//! `LabValue` / `Medication` / `Treatment` / `Visit` / `VitalSign`
//! resolve to the `0x09XX` Health codebook (Northstar T9).

pub mod unified;

mod medcare_bridge;
mod openproject_bridge;
mod redmine_bridge;

pub use medcare_bridge::{HealthcarePort, MedcareBridge};
pub use openproject_bridge::{OpenProjectBridge, OpenProjectPort};
pub use redmine_bridge::{RedmineBridge, RedminePort};
pub use unified::UnifiedBridge;

// Compatibility shims for the pre-migration constants. `bridges`
// previously re-exported `OPENPROJECT_CODEBOOK` / `REDMINE_CODEBOOK`
// directly; both now live in `ogar_vocab::ports::*_ALIASES` (the
// canonical layer is the single source of truth). The re-exports here
// are `#[deprecated]` in the per-port modules and forward to the OGAR
// constants — existing consumers keep compiling (codex P2 on PR #570).
#[allow(deprecated)]
pub use openproject_bridge::OPENPROJECT_CODEBOOK;
#[allow(deprecated)]
pub use redmine_bridge::REDMINE_CODEBOOK;
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ mod tests {
//! `UnifiedBridge<OpenProjectPort>` instead of a local struct.

use super::*;
use crate::bridge::{BridgeError, NamespaceBridge};
use crate::error::Error;
use crate::namespace::NamespaceId;
use crate::namespace_registry::NamespaceRegistry;
use crate::registry::OntologyRegistry;
use lance_graph_ontology::bridge::{BridgeError, NamespaceBridge};
use lance_graph_ontology::error::Error;
use lance_graph_ontology::namespace::NamespaceId;
use lance_graph_ontology::namespace_registry::NamespaceRegistry;
use lance_graph_ontology::registry::OntologyRegistry;
use ogar_vocab::class_ids;
// PortSpec needed in scope for `OpenProjectPort::aliases()` (the
// method is a trait item — codex P1 on PR #570).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ pub const REDMINE_CODEBOOK: &[(&str, u16)] = ogar_vocab::ports::REDMINE_ALIASES;
#[cfg(test)]
mod tests {
use super::*;
use crate::bridge::{BridgeError, NamespaceBridge};
use crate::error::Error;
use crate::namespace::NamespaceId;
use crate::namespace_registry::NamespaceRegistry;
use crate::registry::OntologyRegistry;
use lance_graph_ontology::bridge::{BridgeError, NamespaceBridge};
use lance_graph_ontology::error::Error;
use lance_graph_ontology::namespace::NamespaceId;
use lance_graph_ontology::namespace_registry::NamespaceRegistry;
use lance_graph_ontology::registry::OntologyRegistry;
use ogar_vocab::class_ids;
// PortSpec needed in scope for `RedminePort::aliases()` (the method
// is a trait item — codex P1 on PR #570).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@
//! `P::NAMESPACE`), so downstream context-based routing can
//! distinguish per-port data from the default (unbound) context.

use crate::bridge::{BridgeError, BridgeFromRegistry, EntityRef, NamespaceBridge};
use crate::error::{Error, Result};
use crate::namespace::{NamespaceId, OgitUri, SchemaKind, SchemaPtr};
use crate::namespace_registry::NamespaceRegistry;
use crate::registry::OntologyRegistry;
use lance_graph_ontology::bridge::{BridgeError, BridgeFromRegistry, EntityRef, NamespaceBridge};
use lance_graph_ontology::error::{Error, Result};
use lance_graph_ontology::namespace::{NamespaceId, OgitUri, SchemaKind, SchemaPtr};
use lance_graph_ontology::namespace_registry::NamespaceRegistry;
use lance_graph_ontology::registry::OntologyRegistry;
use ogar_vocab::ports::PortSpec;
use std::marker::PhantomData;
use std::sync::Arc;
Expand Down
9 changes: 9 additions & 0 deletions crates/lance-graph-ogar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ pub use ogar_class_view::OgarClassView;
/// The calcified canonical AR shape (attributes + family `Association`s).
pub use ogar_vocab::Class;

// ── OGAR-driven tenant port bridges (moved out of lance-graph-ontology,
// which is OGIT and must not depend on ogar-vocab) ──
pub mod bridges;

pub use bridges::{
HealthcarePort, MedcareBridge, OpenProjectBridge, OpenProjectPort, RedmineBridge, RedminePort,
UnifiedBridge,
};

/// Codebook parity-guard — the drift fuse between OGAR's authoritative codebook
/// (`ogar_vocab::class_ids::ALL`) and the contract's zero-dep wire mirror
/// (`lance_graph_contract::ogar_codebook::CODEBOOK`). Two depths so it cannot be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! `REDMINE_CODEBOOK`) keyed off the shared
//! `lance_graph_ontology::bridges::codebook::*` constants.

use lance_graph_ontology::bridges::{OpenProjectBridge, RedmineBridge};
use lance_graph_ogar::bridges::{OpenProjectBridge, RedmineBridge};
use ogar_vocab::class_ids as codebook;
use lance_graph_ontology::{NamespaceBridge, OntologyRegistry};
use std::fs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
//! or `BridgeError::NotInScope` (the latter when the namespace itself is
//! present but the public name was filed under a different bridge id).

use lance_graph_ontology::bridges::{MedcareBridge, OgitBridge, WoaBridge};
use lance_graph_ogar::bridges::MedcareBridge;
use lance_graph_ontology::bridges::{OgitBridge, WoaBridge};
use lance_graph_ontology::{NamespaceBridge, OgitUri, OntologyRegistry};
use std::fs;
use std::sync::Arc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//! Woa/Medcare pair — symmetric coverage so the addition can't
//! silently relax the scope-lock guarantee.

use lance_graph_ontology::bridges::{MedcareBridge, OpenProjectBridge};
use lance_graph_ogar::bridges::{MedcareBridge, OpenProjectBridge};
use lance_graph_ontology::{NamespaceBridge, OgitUri, OntologyRegistry};
use std::fs;
use std::sync::Arc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//! cross-fork convergence (pinned in `bridge_codebook_convergence.rs`)
//! lands on a substrate that refuses cross-namespace leaks by default.

use lance_graph_ontology::bridges::{OpenProjectBridge, RedmineBridge};
use lance_graph_ogar::bridges::{OpenProjectBridge, RedmineBridge};
use lance_graph_ontology::{NamespaceBridge, OgitUri, OntologyRegistry};
use std::fs;
use std::sync::Arc;
Expand Down
13 changes: 0 additions & 13 deletions crates/lance-graph-ontology/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,6 @@ keywords = ["ontology", "ogit", "ttl", "rdf", "lance"]
# / SchemaExpander. Zero-dep crate by design — we depend on it, not the reverse.
lance-graph-contract = { path = "../lance-graph-contract" }

# Canonical class schema (codebook + Class fns + PortSpec). The
# `UnifiedBridge<P: PortSpec>` harness in `crate::bridges::unified` is
# parameterised by `ogar_vocab::ports::PortSpec`, so per-port bridges
# (OpenProjectBridge, RedmineBridge, …) are type aliases over the
# harness — the namespace / bridge_id / public-name-alias data all
# come from OGAR class schema, not from this crate.
# OGAR `main` carries `ports::PortSpec` + the project-mgmt ports AND the
# `HealthcarePort` + 0x09XX Health codebook that
# `MedcareBridge = UnifiedBridge<HealthcarePort>` needs (OGAR #91 merged).
# Tracks `main`, matching the sibling `lance-graph-ogar` / `cognitive-stack`
# / `symbiont` pins — one OGAR source for the whole graph.
ogar-vocab = { git = "https://github.com/AdaWorldAPI/OGAR", branch = "main" }

# TTL parser. oxttl is the smallest streaming Turtle parser in the workspace's
# dependency graph and matches the shape of OGIT's per-entity .ttl files.
# Pinned to the same oxrdf version as oxrdfxml below — duplicate-version
Expand Down
63 changes: 10 additions & 53 deletions crates/lance-graph-ontology/src/bridges/mod.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,15 @@
//! Default tenant bridge implementations.
//! Default tenant bridge implementations (OGIT side).
//!
//! # Two layers
//! These are the **legacy per-tenant bridges** with a bespoke struct
//! shape, locked to one OGIT namespace each and routing resolution
//! through the shared registry. They predate OGAR's codebook and have
//! no `PortSpec` impl in `ogar-vocab::ports`.
//!
//! - The **generic harness** [`unified::UnifiedBridge<P: PortSpec>`] is
//! the one-and-only NamespaceBridge impl for OGAR-driven ports. It
//! inherits everything that varies between ports
//! (`NAMESPACE` / `BRIDGE_ID` / public-name → class_id aliases) from
//! [`ogar_vocab::ports::PortSpec`]. Adding a port is `impl PortSpec
//! for FooPort {…}` in OGAR — no bridge boilerplate here.
//! - The **legacy per-tenant bridges** ([`WoaBridge`], [`SpearBridge`],
//! [`SharePointBridge`], [`OgitBridge`]) keep their bespoke struct
//! shape for now. They predate OGAR's codebook and don't yet have a
//! `PortSpec` impl in `ogar-vocab::ports`. When the WorkOrder /
//! EmailCorrespondance / SharePoint namespaces get promoted into the
//! codebook, these collapse the same way OpenProject, Redmine, and
//! MedCare already did.
//!
//! # OGAR-driven ports (`UnifiedBridge<P>` aliases)
//!
//! - [`OpenProjectBridge`]: `UnifiedBridge<ogar_vocab::ports::OpenProjectPort>`
//! — locks to the `OpenProject` namespace. `WorkPackage` / `TimeEntry`
//! / `Project` etc. resolve to OGAR canonical class_ids via the
//! port's alias table.
//! - [`RedmineBridge`]: `UnifiedBridge<ogar_vocab::ports::RedminePort>` —
//! locks to the `Redmine` namespace. `Issue` / `TimeEntry` / `Project`
//! etc. resolve to the SAME OGAR canonical class_ids as the
//! OpenProject equivalents, so cross-fork convergence is the default
//! not the exception.
//! - [`MedcareBridge`]: `UnifiedBridge<ogar_vocab::ports::HealthcarePort>`
//! — locks to the `Healthcare` namespace. `Patient` / `Diagnosis` /
//! `LabValue` / `Medication` / `Treatment` / `Visit` / `VitalSign`
//! resolve to the `0x09XX` Health codebook (Northstar T9). Single-
//! tenant today; a future FMA / SNOMED curator converges on the same
//! ids.
//! The OGAR-driven port bridges (the generic `UnifiedBridge<P: PortSpec>`
//! harness and its `OpenProjectBridge` / `RedmineBridge` / `MedcareBridge`
//! aliases) live in the `lance-graph-ogar` crate (`lance_graph_ogar::bridges`)
//! — they couple to `ogar_vocab::ports` / `ogar_vocab::class_ids`, which is
//! OGAR, not OGIT. This crate (OGIT) must not depend on `ogar-vocab`.
//!
//! # Per-tenant bridges (legacy struct shape)
//!
Expand All @@ -48,32 +25,12 @@
//! its own auth + per-customer scoping concerns that need a separate
//! design pass.

pub mod unified;

mod medcare_bridge;
mod ogit_bridge;
mod openproject_bridge;
mod redmine_bridge;
mod sharepoint_bridge;
mod spear_bridge;
mod woa_bridge;

pub use medcare_bridge::{HealthcarePort, MedcareBridge};
pub use ogit_bridge::OgitBridge;
pub use openproject_bridge::{OpenProjectBridge, OpenProjectPort};
pub use redmine_bridge::{RedmineBridge, RedminePort};
pub use sharepoint_bridge::SharePointBridge;
pub use spear_bridge::SpearBridge;
pub use unified::UnifiedBridge;
pub use woa_bridge::WoaBridge;

// Compatibility shims for the pre-migration constants. `bridges`
// previously re-exported `OPENPROJECT_CODEBOOK` / `REDMINE_CODEBOOK`
// directly; both now live in `ogar_vocab::ports::*_ALIASES` (the
// canonical layer is the single source of truth). The re-exports here
// are `#[deprecated]` in the per-port modules and forward to the OGAR
// constants — existing consumers keep compiling (codex P2 on PR #570).
#[allow(deprecated)]
pub use openproject_bridge::OPENPROJECT_CODEBOOK;
#[allow(deprecated)]
pub use redmine_bridge::REDMINE_CODEBOOK;
5 changes: 3 additions & 2 deletions crates/lance-graph-ontology/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
//! - [`NamespaceBridge`] is the trait every tenant bridge implements. Default
//! methods do the heavy lifting: a typical tenant bridge is ~15-20 lines
//! that lock to one namespace and route resolution through the shared
//! registry. See [`bridges::WoaBridge`], [`bridges::MedcareBridge`],
//! [`bridges::OgitBridge`].
//! registry. See [`bridges::WoaBridge`], [`bridges::OgitBridge`]. The
//! OGAR-driven port bridges (OpenProject / Redmine / MedCare) live in
//! the `lance-graph-ogar` crate (OGAR), not here (OGIT).
//! - [`MappingProposal`] is the producer-side DTO. TTL hydration emits
//! proposals; schema scanners (MySQL/MSSQL, future) and customer admin
//! forms emit proposals; everything funnels through one append path.
Expand Down
Loading