platform/context-graph
A row cannot know that this part fits that machine.
Product data has been stored in tables for thirty years, and tables are excellent at describing one thing at a time. Almost every question worth asking about a catalog is a question about relationships between things.
Left: three rows that cannot see each other · Right: the same records, plus what is true between them
Products, variants, attributes, documents, claims and more.
Compatibility, lineage, provenance, substantiation.
Provenance is an edge, not a nullable column.
Append-only. Any past state remains queryable.
Tables describe things. Catalogs are about relationships.
A spreadsheet row is a complete description of one product in isolation, and for a long time that was enough, because the questions asked of a catalog were also about one product at a time. What does it cost. How many are in stock.
The questions changed. A shopper asks whether it fits. A regulator asks what substantiates a claim. A model asks how it compares. A buyer asks what replaced it. None of those are properties of a product — they are properties of the space between products.
Teams do try to force this into columns. It produces the familiar artefacts: compatible_skus as a comma-separated string, a notes field holding lineage in English, six columns for what is obviously a repeating group.
Each is a relationship, flattened into a cell, where nothing can traverse it and nothing can validate it. The graph is not a fashionable storage choice. It is the shape the data already had.
A relationship encoded as text is invisible to every query, validator and traversal that follows
Nine entities. Forty edges. One shape.
This is the whole model. Everything else on the platform — every agent, every template, every compliance gate — is a traversal of it.
Provenance runs down the right-hand side · classification and lineage across the left
Product
The sellable thing. Holds identity, not values.
Variant
A specific configuration. Colour, size, pack count.
Attribute
One typed value, bound to a unit and a source.
Document
A datasheet, certificate, drawing or artwork file.
Claim
An assertion made publicly. Substantiated or not.
Brand
A resolved entity, not a string in a column.
Category
A leaf node, per standard. Several at once.
Supplier
Who sent it, and which of their documents govern.
Channel
Where a version of this record is published.
variant_of
Product ← Variant
Inheritance with per-variant overrides
has_attribute
Variant → Attribute
Typed, unit-bound, never free text
sourced_from
Attribute → Document
Page and table, not just the file
substantiates
Document → Claim
The edge compliance actually checks
classified_as
Product → Category
One edge per taxonomy standard
compatible_with
Product ↔ Product
Fitment, the query rows cannot answer
supersedes
Product → Product
Discontinued lines and their replacements
published_to
Variant → Channel
With the lossy mapping recorded
Where a value came from is a relationship, not a column.
Most systems that track provenance bolt a source string onto the value and call it done. That works right up until the document is revised, or two documents disagree, or a regulator asks which version of the certificate was on file when the claim was published.
As an edge, provenance gains the properties it needs: a document can be revised without rewriting every attribute that cites it, two sources can both point at one value and be flagged as conflicting, and a claim can be checked against the document that substantiates it as a traversal rather than as a manual review.
Compliance is a traversal: Claim → substantiates → Document → valid_until
Four questions a table cannot answer.
Not slowly. Not expensively. At all — because the relationship the question depends on was never recorded as a relationship.
Every one of these is a question a real team has asked us during an evaluation, usually after describing it as “the thing we currently do in a spreadsheet once a quarter.”
Standards at the edges, not opinions.
The graph is only useful if what enters and leaves it is portable. Identity, units and emission all sit on published standards.
GTIN / GS1 · MPN · internal SKU
Checksum-validated on write
UN/CEFACT common codes
GRM, HUR, KWT, MTR, LTR
Schema.org Product / Offer / Brand
Validated before publish
GraphQL and REST
Traversal depth is a query parameter
Idempotency keys on every mutation
Replays are safe
Signed webhooks on node and edge change
At-least-once delivery
Append-only; corrections are new entries
Any past state is queryable
RBAC scoped by node type and channel
Read paths audited
Your graph is exportable in full — nodes, edges, provenance and history — in a documented format, at any time, without asking us. A context graph you cannot take with you is not an asset, it is a hostage.
Watch your own catalog become a graph.
Send one category. We will build the graph, and hand back the relationships that already existed in your data without being recorded — the compatibility, the lineage, the substantiation — plus the ones that turn out to be missing.
One category · Read-only · Fully exportable · 10 working days