Case Study
GBlocks
A real UK Property Digital Twin -- ~150,000 real properties across 24 open-government sources, built to prove the Source-to-Scene method with real data instead of a synthetic sample.
Evidence & trust
Current evidence status
The case combines reproducible implementation evidence with explicit interpretation. It is supporting evidence for the method, not a delivered client engagement.
- Assessment
- 28/32 Eight-dimension assessment run against live database evidence on 8 July 2026
- Data scope
- 24 sources Approximately 150,000 properties in the bounded UK study area
- Quality control
- Fail-closed Native checks plus a second observability engine share governed results
- Latest review
- 16 July 2026 Municipal and temporal PoCs were independently reviewed and corrected
Use the case to decide whether a bounded Reality Mapping or semantic-readiness follow-up is justified.
- This is a personal research demonstrator, not evidence from a paying client engagement.
- Source-to-Scene still needs a second independent domain before it can claim broad generalisation.
- Satellite observations, official models and administrative records represent different phenomena and must not be treated as interchangeable ground truth.
Context
GBlocks (github.com/steven4320555/GBlocks) is a UK geospatial data platform linking every address and postcode to its full administrative and statistical hierarchy, inspired by Steven's PhD research on a modular, hierarchical, spatial-temporal data framework for GB homes. It was built independently of the Trusted Data Framework -- to explore the thesis's data spine concept -- and only afterwards recognised as the real-data version of the framework's own UK Property Digital Twin reference scenario.
The reference scenario document explicitly states the first demonstration should be synthetic, "should not rely on restricted datasets," and lists specific data issues a synthetic scenario should simulate: mismatched address strings, missing UPRNs, EPC-vs-property address-format mismatches, postcode-vs-Census granularity mismatch, spatial-vs-key matching, and snapshot-vs-live data. GBlocks solved every one of these for real, using real UK government open data (NSPL, ONS boundaries, OS Open UPRN, NSUL, HM Land Registry Price Paid Data, MHCLG EPC, police.uk crime, Ofsted, Companies House, Environment Agency flood zones, ONS Census 2021, OS greenspace/roads, and -- added in a second expansion round -- Historic England Listed Buildings and their curtilage outlines, HM Land Registry Title Boundaries, and DfE Educational Establishments, all via the MHCLG Planning Data Platform), not synthetic samples. 24 sources are declared and governed today, up from the 12+ this case was first written against.
Framework Lens
The case is especially relevant to Reality, Information (Raw/Curated Data), Identity, and the Semantic Layer. It also produced the first real evidence for the Source-to-Scene Pipeline native method.
How the Core Concepts Apply, With Real Examples
Reality Mapping
GBlocks' reality landscape names 12 real-world concepts before any table is designed: Property, Address, Postcode, the OA/LSOA/MSOA/LAD nesting hierarchy, Transaction, Energy Assessment, Crime Incident, School, Company, Flood Zone, Physical Feature, and Population Context. Two concrete examples of Reality Mapping doing real work, not just naming things:
- Three partial representations of one reality. EPC, Price Paid, and OpenStreetMap each describe "a property" differently -- EPC assesses it, Price Paid records a transaction on it, OSM attempts to represent its address. None is complete on its own (EPC only covers properties assessed since ~2008; Price Paid is transactional, not a live register; OSM is crowd-sourced and covers ~20% of the authoritative property count in the study area). Reality Mapping is what makes it possible to say precisely which partial view each source offers, rather than silently treating them as interchangeable.
- A live Reality Mapping failure, caught, not hidden. Mid-build, a layer fetched from the OS Features API (greenspace, roads) returned 100% valid-looking GeoJSON that nonetheless represented every point at the wrong coordinates -- the API returns EPSG:4326 in a different axis order depending on request method (GET vs POST). A geometrically "valid" representation was silently misrepresenting reality. It was caught only because a data quality check asserted "this table should have thousands of rows intersecting the study area" and got zero -- proof that Reality Mapping needs continuous verification, not a one-time exercise.
- "Zero results" investigated as a fact about reality, not assumed to
be a bug. Adding a fifth planning.data.gov.uk dataset
(
planning-application) returned 0 rows for the study area. Rather than debugging the query further on the assumption something was broken, the investigation traced the actual cause: querying the dataset's ownorganisation-entityvalues showed only 4 councils nationally currently publish to this feed, none in Hertfordshire. The reality being mapped genuinely has no data there yet -- a materially different finding from "the pipeline is broken," and one that would have been missed by treating an empty result as self-evidently a defect.
Ontology
semantic/ontology.yaml in the GBlocks repo is a working, if
deliberately lightweight, ontology: 19 concepts (grown from an initial
15 as new sources were added), each with a formal definition, a mapping
to the physical table/fields that implement it, and typed relationships
to other concepts, using a small closed vocabulary (originally 10 types
-- located_in, part_of, represents, refers_to, assesses,
occurred_near, serves, registered_at, constrains, describes --
extended to 12 when two new relationship shapes appeared for real:
same_as, for two sources confirmed or suspected to describe the same
real-world instance, and co_locates, for a spatial correspondence that
hasn't been materialised as a join yet). Three things worth noting:
- Confidence is part of the ontology, not bolted on afterward. The
Transaction refers_to Propertyrelationship is markedconfidence: medium, with an explicit note that only 7.0% resolve to an exact matched UPRN (a conservative fuzzy match) while 92.9% fall back to the coarser postcode-level relationship. A knowledge consumer -- human or AI -- reading the ontology knows how much to trust that relationship before using it, not just that it exists. - Governance facts live inside the model. The
PhysicalFeatureconcept's definition states outright that two of its three source tables (greenspace, roads) are billed OS Premium products, not free OS OpenData, discovered only after the fact via a usage-dashboard check. An ontology that only encoded "what this means" and not "what it costs to keep this true" would miss a real operational constraint. - Duplicate representations were caught before they entered the model,
not cleaned up afterward. While adding four new datasets from the
MHCLG Planning Data Platform, a fifth candidate (
flood-risk-zone) was investigated via schema inspection and recognised as a republication of the EA Flood Zones 2 & 3 data already loaded directly from the Environment Agency. It was never ingested. Ontology discipline here isn't just modelling what's already in the database -- it's recognising, before ingestion, when two differently-labelled sources describe the same real-world concept.
Semantic Layer
GET /semantic-model serves the ontology above as live JSON, not a
static document -- the semantic layer is queryable infrastructure a
downstream AI agent or application could consume directly, the same
pattern the framework's own Semantic Readiness Accelerator looks for.
This is deliberately a Reality Semantic Layer, not a Business
Semantic Layer: it extends meaning across physical objects (Property,
Boundary, Flood Zone), identity, and spatial relationships, rather than
BI metrics or KPI definitions. Self-assessed at Maturity Level 3
("priority concepts, terms, mappings defined for selected use cases")
per the framework's own semantic layer maturity scale -- explicitly not
yet Level 4, since there is no versioning or change-control process
governing edits to ontology.yaml beyond git history.
The model has now been extended once under real pressure (four new
concepts, two new relationship types) without needing to restructure any
of the original 15 concepts -- a small but genuine data point that the
Level 3 scope was drawn in the right place the first time, rather than
an accident of a small initial dataset. A changelog field was added
directly inside ontology.yaml to record what changed and why -- itself
a lightweight, honest step toward the missing Level 4 governance,
short of a full versioning process.
Knowledge Graph
GBlocks deliberately does not build a knowledge graph, matching this
framework's own guidance (ADR004) not to make the graph the centre of
the architecture prematurely. But the relationships a graph would
formalise already exist as queryable, materialised traversal views --
geo.epc_hierarchy, geo.price_paid_hierarchy, geo.crime_hierarchy,
and so on each answer a one-hop question (everything connected to this
property) without graph infrastructure. GET /scene/uprn/{uprn} goes
further: given one UPRN, it assembles identity, every source's
representation, the full boundary hierarchy, a chronological event
timeline (sales, assessments), current state, and per-link confidence
in a single call -- exactly the question a property-centred knowledge
graph node would answer, answered today with a relational/spatial store
and no graph database.
This is itself a useful, evidenced answer to the Knowledge Graph Readiness Accelerator's central question -- "should we build a graph, where, and why?" For GBlocks: not yet. The operational questions asked so far are one-hop ("what does this property look like") and a relational store with good spatial joins answers them well. A graph would earn its complexity the moment questions become genuinely multi-hop -- e.g. "find every property within 500m of an Outstanding- rated school, built before 1950, outside any mapped flood zone, sold in the last two years" -- a query that's awkward as chained SQL joins but natural as graph traversal. GBlocks doesn't need that query yet; a future case that does would be the right trigger to build one.
A concrete example of the gap a graph's entity-resolution layer exists
to close showed up while adding the DfE's Educational Establishment
dataset: it describes the same real-world entity type -- a school -- as
the Ofsted schools dataset already in the spine, using a different
identifier scheme (DfE establishment number vs Ofsted URN), with no
link between them. Today that's honestly recorded as an open gap in
semantic/ontology.yaml (a same_as relationship with confidence: none) rather than silently presented as two unrelated tables. A
knowledge graph's entity-resolution step is exactly the mechanism that
would close a gap like this at scale -- but naming the gap explicitly,
without graph infrastructure, is itself most of the value a Knowledge
Graph Readiness Accelerator engagement would otherwise have to surface
from scratch.
What It Teaches
Evidence added after the original assessment
-
Quality gates now fail closed. Data-quality findings no longer remain warnings that a build can silently ignore. A second observability engine runs alongside the native rules rather than replacing them.
-
Cross-source checks need semantic qualification. A 2.4% overlap between Environment Agency flood zones and routine surface-water observations was expected once the represented phenomena were distinguished. The result is not evidence that either source is wrong.
-
Observation coverage is not unconditional ground truth. The green-space check reports both scene coverage and valid-observation coverage; 94.8% refers to valid observed area, not every square metre at every time.
-
Time has its own trust boundary. Recent Land Registry periods are marked provisional inside a 90-day registration-lag window instead of being presented as a real fall in activity.
-
A useful PoC records rejected scope. Solid was not recommended as the bulk analytical backing store; the narrower user-owned Watchlist slice remained a future evaluation route.
-
A method built for a synthetic reference scenario can turn out to already match a system built for entirely unrelated reasons -- worth actively looking for this kind of accidental validation rather than only building demonstrations to order.
-
Identity resolution at scale is genuinely messy: two independently- sourced authoritative UPRN registers agreeing 99.9% is strong evidence, but the remaining sources (crowd-sourced addresses, event-based transactions with no native identifier) need honestly-stated, not hidden, confidence levels.
-
A data quality/observability layer (a rule-based DQ engine plus pipeline-run logging) turns "trust" from a claim into something machine-checked and re-verified on every rebuild.
-
A semantic layer doesn't need to start as RDF/OWL to be real -- a small, versioned, field-mapped concept model with typed relationships is enough to move from Maturity Level 2 (implicit) to Level 3 (explicit, per-use-case) and be genuinely useful to a consuming API.
-
A reusable access-method pattern can emerge mid-project, not just at design time: streaming a remote bulk file with a server-side filter (DuckDB's
httpfsextension) turned out to be dramatically more reliable than a source's own live query API for large datasets -- confirmed directly across four datasets, not assumed from one. -
Growing a system honestly means it will surface its own new gaps, not just new capability -- adding one more source revealed an existing, unaddressed entity-resolution problem between two already-loaded sources. Treating that discovery as a finding to record, not a defect to quietly patch over, is what keeps a semantic model trustworthy as it scales.
Consulting Use
Use this case as the primary evidence base for the Trusted Data Discovery
Accelerator and as the first real validation of the Source-to-Scene
Pipeline native method (see lib/athena-registry.ts,
source-to-scene-pipeline: promoted from Hypothesis to Pattern,
confidence 40 -> 62, on the strength of this case). A full Capability 1
assessment report, a modelled semantic layer, and formal identity/
coverage registers exist in the GBlocks repo itself
(notes/CAPABILITY_1_ASSESSMENT_GBLOCKS.md,
semantic/ontology.yaml, notes/IDENTITY_LINKAGE_REGISTER.md,
notes/COVERAGE_GRANULARITY_MATRIX.md) and can be walked through live
(GET /semantic-model, GET /scene/uprn/{uprn},
GET /reports/reality-mapping).
Next Research Questions
- Does the Source-to-Scene method generalise to a second, independent reference scenario (different domain or region), or is its current fit specific to spatial/property data?
- What would a formal ownership and change-control process for
semantic/ontology.yamllook like in practice, once more than one person maintains it? - Can the Coverage and Granularity Matrix pattern be reused as-is for a non-spatial domain, or does it need generalising beyond the spatial framing in its current template?
- Is the school/educational_establishment entity-resolution gap worth fixing now (a conservative fuzzy name+postcode match, the same pattern already proven for Price Paid), or is naming it and leaving it open a legitimate governance choice until a real use case needs the merged view? Answering this for one small case may be a useful input to a more general Entity Resolution pattern this framework doesn't yet have.