Skip to content

Serve raw ontology graphs without RDFS inference; token-safe @typeof matching - #337

Open
namedgraph wants to merge 1 commit into
developfrom
raw-ontology-serving
Open

Serve raw ontology graphs without RDFS inference; token-safe @typeof matching#337
namedgraph wants to merge 1 commit into
developfrom
raw-ontology-serving

Conversation

@namedgraph

Copy link
Copy Markdown
Member

Problem

View blocks rendered as generic property lists instead of executing their spin:query. Root cause: OntologyFilter materialized an RDFS-inferred imports closure, and ProxyRequestFilter's namespace short-circuit served proxied ?uri= requests via DESCRIBE over that inferred model. ldh:View a rdfs:Class + rules rdfs7b/rdfs9 type every instance rdf:type rdfs:Resource, so proxied ontology documents carried an extra type on every term — producing multi-token @typeof that the client's exact-equality *[@typeof = '&ldh;View'] match no longer satisfied.

Changes

No RDFS inference over application ontologies. An audit showed the reasoner was vestigial: constructors recurse over direct superclasses, SPIN constraint collection walks rdfs:subClassOf itself, and every client ontology query already uses (rdfs:subClassOf)* property paths. The owl:imports closure is now resolved natively by ontapi (OntModelFactory.createModel over a new ScopedGraphRepository view) as a live union graph — the manual flatten/infer/materialize pipeline is deleted. rdfs:Class terms are promoted to owl:Class in a separate union member (ontapi's OWL2 named-class factory doesn't recognize bare rdfs:Class, and its legacy-compat config control only applies to OWL1/expression factories), so no document graph is polluted. Closure union graphs are cached in a bounded map on Application; per-request OntModel wrapping is preserved.

Raw document graphs on the wire, uniformly. The shared repository now only holds raw per-document graphs. ProxyRequestFilter serves closure documents with their raw graphs — asserted triples only, identical to a direct document GET — guarded by isCached so arbitrary external URIs can't trigger repository loading outside the SSRF-validated external-client path. The DESCRIBE fallback remains for terms minted in external namespaces and is now inference-free. Namespace's no-query GET reuses the shared raw cache instead of a per-request createRepository SPARQL round-trip. Invalidation updated in ClearOntology and ValidatingModelProvider.

Token-safe @typeof matching. All 28 exact-equality @typeof comparisons in the client XSLT (View/Object/query/chart blocks, View pager/mode/order/facet handlers) switch to tokenize(@typeof, ' '), per RDFa's whitespace-separated list semantics — any legitimately multi-typed resource would have degraded the same way.

Also fixed in passing: UninstallPackage no longer reads a materialized closure when a package URI is a loaded app ontology, and admin ontologies importing each other can no longer fold one closure's artifacts into another on the shared system repository.

Test plan

  • Full unit suite: 90/90 pass. OntologyImportsCharacterizationTest rewritten to pin: eager closure resolution, zero inference in the union, raw document graphs untouched (isomorphism), promotion not leaking into raw graphs, getOntClass recognition of rdfs:Class-only terms, import-cycle tolerance
  • http-tests/proxy/GET-proxied-ontology-ns.sh extended: proxied ontology document contains the authored classes and no rdf:type rdfs:Resource; same negative assertion on the DESCRIBE fallback
  • Stack rebuild + http-tests run (proxy/, admin/model/, form/constructor suites)
  • Browser: View block on the homepage executes its query and renders the table; single-token typeof in the DOM

🤖 Generated with Claude Code

…matching

Resolve the application ontology's owl:imports closure natively via
ontapi (OntModelFactory.createModel over a ScopedGraphRepository view)
instead of manually flattening the closure and materializing an
RDFS-inferred model. No inference is applied anymore — every consumer
(constructor/constraint inheritance, client-side (rdfs:subClassOf)*
queries) traverses hierarchies explicitly. rdfs:Class terms are promoted
to owl:Class in a separate union member so no document graph is
polluted; closure union graphs are cached in a bounded map on
Application, keyed by ontology URI.

The shared repository now only ever holds raw per-document graphs, which
ProxyRequestFilter serves directly for closure documents — asserted
triples only, identical to a direct document GET. The DESCRIBE fallback
over the in-memory closure (terms minted in external namespaces) is
inference-free as well. This fixes inferred rdf:type rdfs:Resource
leaking into proxied namespace documents, where the extra type produced
multi-token @typeof and silently degraded View blocks to a generic
property list.

Client-side, all exact-equality @typeof comparisons switch to
token-aware tokenize(@typeof, ' '), per RDFa's whitespace-separated
list semantics.

Co-Authored-By: Claude Fable 5 <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

None yet

Development

Successfully merging this pull request may close these issues.

1 participant