Skip to content

Retire the LDT namespaces; the app ontology becomes a dataspace ontology - #394

Merged
namedgraph merged 2 commits into
developfrom
rename/dataspace-vocabulary-retire-ldt
Sep 25, 2026
Merged

namedgraph merged 2 commits into
developfrom
rename/dataspace-vocabulary-retire-ldt

Conversation

@namedgraph

@namedgraph namedgraph commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

Two names in the vocabulary had outlived what they identified. Both are breaking, so both land in 6.0.0 while it is still unreleased.

https://www.w3.org/ns/ldt is retired

LDH stopped being a Linked Data Templates implementation when the API became the Graph Store Protocol, and the template machinery (ldt:Template, ldt:match, ldt:path) has been dead code since. Three terms were still doing ordinary work under the borrowed name, on a host AtomGraph does not own.

  • ldt:ontology, ldt:service, ldt:base → lds:ontology, lds:service, lds:base
  • Deleted: ldt.ttl, the vendored com.atomgraph.server.vocabulary.LDT, rdfs:subClassOf ldt:Application on the dataspace class, the &ct; entity and two unused &c; entities
  • lacl:requestAccess — the one live use of ns/ldt/core/domain# — now ranges over foaf:Document
  • dh: is re-hosted, not reshaped: https://www.w3.org/ns/ldt/document-hierarchy# → https://w3id.org/atomgraph/linkeddatahub/document-hierarchy#. Prefix, class names and both DH.java classes are untouched, so only the namespace string moves.

lapp: becomes lds:

lapp.ttl → lds.ttl, …/linkeddatahub/apps# → …/linkeddatahub/dataspaces#. The unit has been a dataspace since 5.1.0 everywhere except here.

  • lapp:Application/EndUserApplication/AdminApplication → lds:Dataspace/EndUserDataspace/AdminDataspace, with their three *Constructor individuals
  • lapp:application — the Link relation naming the dataspace a response belongs to — → lds:dataspace
  • Java: the com.atomgraph.linkeddatahub.apps package → …dataspaces, LAPP → LDS, the three interfaces and six impls renamed, and getApplication()/getAdminApplication()/getEndUserApplication() → getDataspace()/getAdminDataspace()/getEndUserDataspace() (208 call sites that would otherwise return a Dataspace from a method named for an application)
  • com.atomgraph.linkeddatahub.Application and the three Application*Factory/Filter classes keep their names. Renaming the model removes the collision that had 169 references written fully qualified.

The file was never an "applications" vocabulary — it is the deployment-configuration one, already holding Dataset and Package — so the three incoming LDT terms land here too, and config/dataspaces.trig and config/system.trig each need one prefix where they needed two.

Judgment calls worth a reviewer's eye

  • lds:prefix and lds:versioningRepository are now declared. Both appear in config/dataspaces.trig and are read in Java, but neither was in the ontology, so neither had a label.
  • lds:Context is deliberately not declared — it is an XSLT parameter name, not a term any data carries, matching ldh:requestUri, which is also undeclared.
  • lapp:frontendProxy is dropped rather than renamed. Nothing read it; the proxy that cache-invalidation BANs use has always come from the ldhc:frontendProxy servlet parameter set from FRONTEND_PROXY. lds:backendProxy stays — DatasetImpl reads it for a proxied lds:Dataset.
  • ldh:service is untouched and is not a duplicate of lds:service. It names the endpoint a saved query or content block runs against; lds:service is a dataspace's authoritative backing store, read at bootstrap from the context dataset. Different relations, each in the vocabulary that owns its subject.
  • lds.ttl 1.1.4 → 2.0.0 and dh.ttl 1.1.5 → 2.0.0, since both namespaces changed.
  • No migration. An existing deployment re-seeds: every dataspace is typed in the old namespace and every document in the old document-hierarchy one. CHANGELOG.md says so explicitly.

Verification

  • mvn test: 223 platform tests, 109 CLI tests, all green — including OntologyClosureCIReproTest (parses the real prefix-mapping.ttl) and ResponseHeadersFilterTest (the Link relations)
  • make sef compiles the client SEF; both SSR entry stylesheets (xsl/layout.xsl, xsl/admin/layout.xsl) compile under Saxon-HE Java. SaxonJS cannot compile them — the use-when duals leave ac:langs() undefined for it — so the SSR check has to go through Saxon-HE.
  • 173 RDF and SPARQL files validate with riot/qparse, the five SPIN sp:text bodies in lds.ttl included
  • linkeddatahub.com's and LTLOD's own client.xsl and layout.xsl still compile against the renamed platform tree

Not in this PR

  • The HTTP test suite has not been run. It needs make drop + a re-seed, which wipes the local stack, and the gitignored sef/ cache still holds stale compiled stylesheets that must be purged first.
  • Downstream repos are changed but uncommitted, on their own branches: Web-Client (two lines in ns.ttl plus a test fixture — inert until 6.0.2 ships and both client:6.0.1 pins are bumped, since ns.ttl reaches LDH from the released jar), linkeddatahub.com, LTLOD, LinkedDataHub-Apps. linkeddatahub.com's committed files/client.xsl.sef.json needs make sef re-run after a new LDH image is built — its target compiles against the published image, so recompiling now would bake in the old namespaces.
  • AtomGraph/Core needs nothing — verified, zero references.

Pre-existing bug left alone

dataspaces/model/impl/DatasetImplementation.java:44 throws "Cannot convert node … to Dataspace: it does not have rdf:type lds:Dataspace" while canWrap checks LDS.Dataset. It said Application/lapp:Application before, so it is a copy-paste from the sibling class rather than something this rename introduced. PackageImplementation gets it right.

Second commit: two ACL vocabulary fixes

Independent of the rename, found while checking whether lacl: could be retired alongside the LDT namespace. It cannot — it is LDH-owned and the rest of it is live — but the ontology and its Java mirror had drifted in opposite directions:

  • lacl:CreatorAuthorization was declared and referenced nowhere; lacl:OwnerAuthorization is what AuthorizationFilter actually mints and was declared nowhere. LACL.java, createOwnerAuthorization(), its three tests and http-tests/access/owner-authorization.sh all name the latter. Renamed rather than added, since nothing ever emitted the old name, and its comment now says what the filter does with it.
  • lacl:requestAgentGroup is removed — constant, declaration and write. AccessRequest copied acl:agentGroup off a submitted authorization onto the stored request, and nothing read it back: imports/acl.xsl rebuilds the authorization from requestAgent, requestAccessTo, requestAccessToClass and requestMode, with no branch for the group. The property was written into every group request and dropped again at approval. Group authorizations are not wired through the UI at all — modal.xsl still carries TO-DO: support acl:agentGroup — so completing that round trip is a feature, not a fix, and can add the term back when it lands.

Audited both directions afterwards: all nine LACL.java constants resolve in lacl.ttl and every one is used; every term lacl.ttl declares is either used outside it or is a SPIN constraint/constructor attached to lacl:AuthorizationRequest.

It rides on this branch rather than its own because lacl.ttl is already in this diff, and because switching branches in this working tree is hazardous — config/dataspaces.trig carries a skip-worktree bit and config/system.trig holds local demo-dataspace blocks. Happy to split it out if you would rather review it separately.

🤖 Generated with Claude Code

…r was true.

Two names had outlived what they identified, and both are in the vocabulary, so
both are breaking.

https://www.w3.org/ns/ldt is the Linked Data Templates namespace. LDH stopped
being an LDT implementation when the API became the Graph Store Protocol, and the
template machinery - ldt:Template, ldt:match, ldt:path - has been dead code since.
Three terms were still doing ordinary work under the borrowed name, on a host
AtomGraph does not own: ldt:ontology, ldt:service and ldt:base. They move to
lds:ontology, lds:service and lds:base. ldt.ttl, the vendored LDT Java class, the
rdfs:subClassOf ldt:Application on the dataspace class and the two dead sibling
namespaces go with them; lacl:requestAccess, the one live use of ns/ldt/core/domain#,
now ranges over foaf:Document.

dh: is re-hosted rather than reshaped - w3.org/ns/ldt/document-hierarchy# becomes
w3id.org/atomgraph/linkeddatahub/document-hierarchy#. Prefix, class names and both
DH.java classes are untouched, so only the namespace string moves.

lapp.ttl becomes lds.ttl, .../apps# becomes .../dataspaces#, and lapp:Application,
lapp:EndUserApplication and lapp:AdminApplication become lds:Dataspace,
lds:EndUserDataspace and lds:AdminDataspace with their constructors. lapp:application,
the Link relation naming the dataspace a response belongs to, becomes lds:dataspace.
The file was never an "applications" vocabulary - it is the deployment-configuration
one, holding Dataset and Package alongside the app classes - so the three incoming
LDT terms land here too, and config/dataspaces.trig and config/system.trig each need
one prefix where they needed two.

Three terms used in config and read in Java were never declared; lds:prefix and
lds:versioningRepository now are. lds:Context is not, matching ldh:requestUri: it is
an XSLT parameter name, not a term any data carries. lapp:frontendProxy is dropped
rather than renamed - nothing read it, and the proxy that cache-invalidation BANs use
has always come from the ldhc:frontendProxy servlet parameter.

Java follows the model: the apps package is dataspaces, LAPP is LDS, and
getApplication()/getAdminApplication()/getEndUserApplication() are
getDataspace()/getAdminDataspace()/getEndUserDataspace() - 208 call sites that would
otherwise return a Dataspace from a method named for an application. The JAX-RS
Application class and the three Application*Factory/Filter classes keep their names;
renaming the model actually removes the collision that had 169 references written
fully qualified.

There is no migration. 6.0.0 is unreleased and its migration notes already run long;
an existing deployment re-seeds, because every dataspace is typed in the old namespace
and every document in the old document-hierarchy one.

Verified: 223 platform tests and 109 CLI tests green, including the two that read the
real prefix-mapping.ttl and the Link relations. make sef compiles the client SEF, and
both SSR entry stylesheets compile under Saxon-HE Java - SaxonJS cannot compile them,
since the use-when duals leave ac:langs() undefined for it. 173 RDF and SPARQL files
validate with riot and qparse, the five SPIN bodies in lds.ttl included, and
linkeddatahub.com's and LTLOD's own stylesheets still compile against the renamed
platform tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ds is gone.

Two slips in opposite directions, found while checking whether lacl: could be retired
alongside the LDT namespace. It cannot - it is LDH-owned and the rest of it is live -
but the vocabulary and its Java mirror had drifted.

lacl:CreatorAuthorization was declared and referenced nowhere. lacl:OwnerAuthorization
is what AuthorizationFilter actually mints - LACL.java, createOwnerAuthorization(), its
three tests and http-tests/access/owner-authorization.sh all name it - and it was
declared nowhere. That reads as a rename that landed in the code and not in the
ontology, so the class is renamed rather than added, and its comment now says what the
filter does with it: granted in memory to a document's owner with acl:Read, acl:Append
and acl:Write, before the ACL query runs, and never stored.

lacl:requestAgentGroup goes the other way. AccessRequest copied acl:agentGroup off a
submitted authorization onto the stored request, and nothing ever read it back:
imports/acl.xsl rebuilds the authorization from lacl:requestAgent, lacl:requestAccessTo,
lacl:requestAccessToClass and lacl:requestMode, and has no branch for the group. The
property was written into every group request and dropped again at approval. It was
also the one term LACL.java declared that lacl.ttl did not, so rather than declare it
and keep writing data no reader consumes, the constant, the declaration and the write
are removed. Group authorizations are not wired through the UI at all - modal.xsl still
carries "TO-DO: support acl:agentGroup" - so completing the round trip is a feature, not
a fix, and can add the term back when it lands.

Audited both directions afterwards: all nine LACL.java constants resolve in lacl.ttl,
every one of them is used, and every term lacl.ttl declares is either used outside it or
is a SPIN constraint or constructor attached to lacl:AuthorizationRequest, which is how
those four are meant to be reached.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@namedgraph
namedgraph force-pushed the rename/dataspace-vocabulary-retire-ldt branch from bbe3fd6 to 22abec4 Compare September 25, 2026 16:33
@namedgraph
namedgraph merged commit e92b1da into develop Sep 25, 2026
2 checks passed
@namedgraph
namedgraph deleted the rename/dataspace-vocabulary-retire-ldt branch September 25, 2026 18:30
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