Chapter 18. Building Up

This chapter runs the synthesis direction constructively, presenting the synthesis theorem as a build log. Start with the derived atoms and compose a working application space, defining each layer by what Part II forced and each concrete technology by the factor it implements.

The dataspace

What the synthesis yields needs a name, and the name should do for state what “website” did for documents. Call it a dataspace: one party’s stake in the data web, the unit of publication, ownership, and federation. A website serves documents under an origin; a dataspace serves state under an origin. Documents are included, since they are projections of that state. Machines can consume it too, since the names in the state can be dereferenced. The definition needs one primitive Part II never used, and the web already provides it. Chapter 1’s pattern holds one last time:

O        the set of origins                               (RFC 6454)
I∣o      the URIs under origin o

An origin is not a new kind of name. RFC 6454 computes it from the URI (scheme, host, port), so O is a quotient of I: many URIs, one origin. The namespace falls into regions, one per party, and “one party’s stake” acquires a type. The definition has four components and no more: one origin and three names in that origin’s region. The three can be names because on the web every published thing is a name:

Dataspace = (o, ont, e, x)      o ∈ O;   ont, e, x ∈ I∣o   (18.1)
name component gloss
o the origin read-write linked data at every document under it
ont the ontology what the domain is, stated as one namespace
e the SPARQL endpoint the same state, projected by query
x the stylesheet declarative rendering, extended by override

Internal storage (file, memory, triplestore) has no row. It is invisible to consumers, as S1 demands.

Behind the four names stands one state S, in the shape of Prop. 9.2: quads, grouped by their fourth position into a family of named graphs. S(u) is the graph named u, and every graph name is a document URI under o. The gloss column is then four laws: each restates an earlier result as a rule of deployment.

Documents

Dereference is graph lookup — select(u, S) = S(u), the fourth position as the address (Prop. 9.2). There read is defined (S4) and write accepts a delta (Prop. 7.1). And the obligation that makes the data linked: every name under o in a fact position of S has read(name, S) defined — mint a name only if you serve its description. AWWW §3.5 asked for this as a SHOULD; (18.1) holds it as a condition of being a dataspace at all. So the state is not only composable but recursively discoverable: each reference in a fact is an address, and dereferencing it returns more state, whose references point onward in turn. Practitioners know this as “follow your nose”. Documents may also nest. Parent and child are ordinary facts, so a document’s children are one more selection. Addressing stays flat (one graph per document) and the hierarchy is a convention over it, not a new kind of resource.

One state

The endpoint e answers ⟦q⟧ posed to S itself, the same S the documents project. “Projecting the same state” is an equation: a document serves facts and the endpoint returns facts, both come from one S, so they must agree. If a second store drifts from S, the agreement breaks observably.

Domain as data

S(ont) is schema in the shape of (5.3): the domain’s classes and properties are stated as facts, so the ontology is ordinary state and merges by union. The build log below shows what reads it.

Total rendering

x dereferences to the arrange term, generic in B.8’s sense. The build log below looks at it more closely.

One entity makes the four concrete. GET …/panel-14 returns the graph of facts about that panel. PATCH …/panel-14 sends a delta, (D⁻, D⁺). And the endpoint answers any query that ranges over it. One state is reachable three ways, and each is an HTTP request you can make by hand.

The write side has four methods, and each is Prop. 7.1’s delta with part of it fixed; PATCH is the general case, and POST, PUT, and DELETE are special cases:

method fixes result
POST D⁻ = ∅ S′ = S(u) ∪ D⁺ append (a merge)
PUT D⁻ = S(u) S′ = D⁺ replace, creating if absent
DELETE D⁻ = S(u), D⁺ = ∅ S′ = ∅ remove
PATCH any D⁻, D⁺ S′ = (S(u) ∖ D⁻) ∪ D⁺ general

The Graph Store Protocol leaves PATCH informative; realized, it is a graph-scoped SPARQL Update. HTML forms speak only POST, so a form’s delta arrives through the RDF/POST bridge (Chapter 9). Zoom out from one graph to the whole dataset and the same four return on quads: GET a dataset, POST appends quads, PUT replaces it, DELETE removes it, the extended form some triplestores implement.

PATCH — any D⁻, D⁺. The general write; the other three are it at a fixed delta.
S — the graph …/panel-14
(⟨…#panel-14⟩, type, ⟨…#Panel⟩)
(⟨…#panel-14⟩, title, "Current Power")
(⟨…#panel-14⟩, value, "15.5 kW")
(⟨…#panel-14⟩, partOf, ⟨…#farm⟩)
D⁻ — removed
panel-14 value "15.5 kW"
D⁺ — added
panel-14 value "16.1 kW"

Interactive exhibit (online edition): the write methods on …/panel-14. Pick GET, POST, PUT, DELETE, or PATCH. The delta (D⁻, D⁺) snaps to that method’s row, and the graph updates by S′(u) = (S(u) ∖ D⁻) ∪ D⁺. The same panel graph the chapter reads, now writable by hand.

(18.1) omits S itself: neither the state nor the store holding it is a component. A consumer sees only the four projections, so the store is invisible by definition rather than by an implementer’s discipline. That lifts S1 from one factor to the whole system. Two deployments with the same four projections are the same dataspace.

And the union law returns. Federation adds one thing to prove, and B.9 proves it from the types alone. Distinct origins are disjoint regions of I, so two dataspaces’ graph names never collide, and the union of their states is again well-formed. Every document is still under exactly one origin, and attribution survives the merge because the fourth position carries it. Federation is the union law: merge, and be done.

The cost of alignment

Merge, and be done. Chapter 5‘s scope note deferred an objection, and here it returns at full strength: union is cheap; alignment is not. Two dataspaces describe the same turbine. Each minted its own name, because minting is free. The union holds two disconnected descriptions and joins nothing. Two ontologies cover the same domain and share no term. The merge laws guaranteed mechanics, never convergence: nothing makes independent parties end up sharing names and terms. Alignment is the missing step: stating that the two names denote one turbine and that the two vocabularies’ terms correspond. So, says the objection, the model has merely moved the integration cost it claimed to remove. Granted: it moved from the merge to the alignment, and that position makes the difference. The cost is universal, because no model makes strangers agree on names. So the question is never whether alignment costs, but what you hold before aligning, and what aligning yields.

Before aligning: the unaligned union is well-formed state. Both descriptions are present, queryable, and published, and both are rendered by the vocabulary-blind base term the build log below introduces (B.8). The worst case here is not yet joined; in every other column of the audit the worst case is cannot merge (two JSON documents do not compose at all, and two schemas do no better).

After aligning: an alignment is one more fact, an equivalence, a subclass, a subproperty, in the shape of (5.3). The fourth position attributes it to its asserter (Prop. 9.2), it can be retracted as a delta (Prop. 7.1), and it composes by union like everything else. A mapping published this way is stated once and serves the whole web. The integration industry holds the same knowledge as a join buried in pipeline code, once per pair of systems. It has no asserter, cannot be shared, and costs N × M forever.

Even the failure mode improves. The known hazard of alignment is the careless identity link: assert that two names denote the same entity when they do not, and the error spreads through every join that uses the link; the literature rightly distrusts it. In this model a wrong link is at least a published fact: anyone can see it, its asserter is recorded, and a delta retracts it. The same mistake in an integration pipeline is a wrong join key buried in code: no one outside can see it, and nothing can retract it.

And convergence has a deployed existence proof at full web scale. Vocabularies converge the way the document web converged: by adoption, not negotiation. Publish, dereference, reuse, the same unilateral move as linking to a page whose owner was never asked. Schema.org spread across tens of millions of sites in exactly this shape, because consumers with reach (the search engines) made the alignment worth making. Vocabularies get aligned when consumers need them aligned; when the semantic web shipped in the nineties, its consumers did not exist yet (Chapter 8). The substrate was built for machine consumption and standardized twenty years before machines consumed it, so every cost of convergence went unmet. The idea was not refuted; nobody yet needed convergence enough to meet those costs.

The build log

The build log takes the least familiar factor first. The ontology is the component the derivation predicts and the industry outsources to code: the domain, stated as facts. A dataspace’s ontology imports the vocabularies it builds on (union applied to schema) and everything downstream reads it as data. Forms are constructed from it (Chapter 7’s construction half: read the patterns, render inputs); selections range over it; layouts match on it. This is what makes the generic engine generic: the domain travels in the state, so nothing domain-shaped remains to be hardcoded.

The build log, factor by factor:

factor implemented by the derived result, deployed
state a triplestore behind the Graph Store Protocol — the SPARQL suite’s HTTP companion, whose direct graph identification makes the request URI the graph name — one named graph per document the fourth position (Prop. 9.2) as an address — attribution and location coincide
domain a namespace ontology per dataspace, importing the vocabularies it builds on imports resolve by union — vocabulary is data and composes like it
select a SPARQL endpoint per dataspace S4: query results and graphs are resources with URIs of their own
arrange XSLT over the canonical serialization — a base stylesheet naming no vocabulary, per-vocabulary overrides layered by the language’s import mechanism Chapter 6’s seam filled; S3’s substitution, performed in daily practice
present CSS in continuous service since 1996
write HTML forms encoding graphs (Chapter 9’s RDF/POST bridge, deployed in Chapter 19), written through the Graph Store Protocol’s unsafe methods Chapter 1’s unsafe methods applied per graph — POST appends, PUT replaces, DELETE removes; the delta itself a PATCH, a graph-scoped SPARQL Update carrying its two sets

The build log as a picture: the pipeline (4.1) realized in deployed technologies, closed as in Chapter 7. Along the read path the endpoint e runs select (SPARQL), the stylesheet x runs arrange (XSLT, ⟦t⟧ ∘ canon), CSS runs present, (18.1)’s components bound to deployed standards. The return arrow is the write side: a form (Chapter 9’s bridge) yields a delta (D⁻, D⁺) (Prop. 7.1), carried as a PATCH, a graph-scoped SPARQL Update. Under S4 every rounded node is a web resource with a URI of its own.

Arrangement

Arrangement carries the most machinery in the build log. The arrange term may treat a name specially only if the dataspace’s ontology, with its imports, declares it — a custom UI gets its special cases by declaring the vocabulary it renders. That is B.8’s relative genericity, running in deployment. Unmatched state falls back to the base rendering rather than to nothing: every graph renders; declared vocabulary renders better. The stylesheets share their templates across the wire: one library, imported by a server-side stylesheet that emits documents and a browser-side one that binds events. Saxon runs the first and SaxonJS with IXSL runs the second, so two XSLT 3.0 processors share one set of terms. That is Chapter 7’s mobility of evaluation in production: the same terms evaluate on the server and in the browser. The convergence shares rendering code too, by running the same framework on both sides (Chapter 14’s hydration); here the sides share templates without sharing an engine, because the language’s semantics is closed. And independent evolution shows up as operations rather than theory: data, selection, layout, and style invalidate independently, one factor at a time and one cache entry at a time. The four timelines run as infrastructure.