Chapter 2 — The domain model: one graph, one metamodel¶
What the knowledge actually is. This chapter describes the semantic metamodel — the node and edge vocabulary every repository in the constellation conforms to — and the three design commitments that give it its shape: Cypher is the source of truth, one metamodel version governs at a time, and identity is a five-field contract.
2.1 Cypher is the source of truth¶
The metamodel's own preamble states the rule that governs everything else: the
human-readable metamodel document is a projection of the Neo4j schema files under
rosetta-platform/db/schema/, and when the document and a .cypher file disagree,
the Cypher wins. The Cypher is tested in CI; the Markdown is not. Editing the Markdown
does not change the schema — it merely re-projects it.
This is the local form of the constellation-wide invariant (ADR-RX-002, "graph is canonical"): every manifest, ADR, and DecisionTrace in the system is a projection of graph state, and a divergence between projection and graph is a bug. An assessor should read this as the platform's deepest architectural commitment — it decides where truth lives in every dispute — and also as its standing risk: projections can lag (Chapter 10 inventories the places where, at snapshot time, they do).
The governing version at snapshot is metamodel v1.11.0, projected as a 4,457-line document from 46 schema files. Version bumps are cross-repo decisions, never unilateral: the v1.6→1.7 bump (engagement digital twin) was authorized by ADR-RX-008 and implemented by ADR-PL-020; v1.7→1.8 (canvas dimensions) by ADR-RX-009/ADR-PL-021; v1.8→1.9 (delivery spine) by ADR-RX-010/ADR-PL-022; v1.9→1.10 (provenance lane) by ADR-RX-017; v1.10→1.11 (the ratification state machine) by DT-RX-022. The version history is the architecture history, and each section of it names the decision that authorized it.
2.2 The three-layer spine¶
The core of the graph is a three-layer map from what a practitioner wants to what the platform does:
flowchart TB
subgraph L1["Layer 1 — Business Intent"]
BI[BusinessIntent] -->|USES_TERM| VT[VocabularyTerm]
end
subgraph L2["Layer 2 — Semantic Structure"]
SE[SemanticEntity]
CP[ContextPattern]
end
subgraph L3["Layer 3 — Platform Binding"]
PO[PlatformObject] -->|INVOKES| EF[EngineFunction]
end
BI -->|EXPRESSES_AS| SE
CP -->|ADDRESSES| BI
CP -->|REFERENCES| SE
CP -->|RECOMMENDS| EF
SE -->|MAPS_TO| PO
- Layer 1 is the practitioner's business language: "unify customer profiles," "build a 360-degree view."
- Layer 2 is the ontological middle:
SemanticEntitydefines canonical concepts ("Individual," "UnifiedAccount");ContextPatterndefines validated implementation plays ("Hybrid Commerce Identity Resolution"). - Layer 3 is what actually runs on the target platform: the
Individual__dlmdata-lake object, the Identity Resolution engine function.
ContextPattern is the only node type that spans all three layers — it addresses
intents, references entities, and recommends engine functions — which is why it is the
primary retrieval target: enter the graph from any layer and land on the pattern that
bridges them. Everything else hangs off this spine: sessions recommend patterns,
decisions are captured against them, ADRs govern them, metadata observations match them.
2.3 The full graph, grouped¶
Around the spine, the node catalog organizes into seven concerns (40 node types and 62 declared edge types at the v1.9.0 totals; the v1.10/v1.11 deltas added lane properties, not labels):
| Group | Node types | What it holds |
|---|---|---|
| Core | BusinessIntent, VocabularyTerm, SemanticEntity, ContextPattern, PlatformObject, EngineFunction, EnablementSession | The three-layer canon |
| Governance | ADR, DecisionTrace, PromotionCandidate, GovernanceReview, QualityFlag, SpecManifest, DeploymentTarget | The three-gate decision record (Chapter 6) |
| Identity & methodology | Practitioner, PSTNode | Who works, and the Phase-Stage-Task methodology as graph |
| Engagement partitioning | Client, Engagement, SourceArtifact | The tenancy spine: Client -HAS_ENGAGEMENT-> Engagement, everything engagement-scoped BELONGS_TO its engagement |
| Engagement twin (v1.7.0) | ContextArtifact, unified DecisionTrace (traceKind: forensic\|runtime), Alternative, ProvenanceEntry |
The living engagement model of Chapter 5's journey |
| Canvas + delivery spine (v1.8–1.9) | D360UseCase, CapabilityAssessment, DataReliabilityRisk, EvidenceItem, EngagementReadiness; DeliveryWave, DeliveryEpic, DeliverySprint, WorkPacket | Advisory scorecard dimensions and the wave→epic→sprint→work-packet cadence, all engagement-local, all BELONGS_TO -> Engagement |
| Document & context intelligence | SLDCTransition, TagProposal, ValidationCriteria; ContextObservation, QueryTrace, KnowledgeGap, InferredIntent, IngestionSource, IngestionEvent | Source-document lifecycle and confidence-tiered inference |
Two structural rules keep this from sprawling. Engagement-local labels (the canvas and
spine families) are deliberately non-inheritable — they must not overload the
identity-bearing ContextArtifact — and their intra-engagement edges are
partition-isolated (both endpoints must share an engagement, enforced by invariant
gates). And the delivery spine's merge keys are engagement-local
('nto-01::E1-S1-WP1'), not global identities.
2.4 The five-field identity contract and the domain stack¶
The system's answer to "how does canon get reused without being copied" is the domain stack. Eight node types are inheritable — ContextPattern, ADR, BusinessIntent, VocabularyTerm, SemanticEntity, PlatformObject, EngineFunction, and (since v1.7.0) ContextArtifact — and every node carrying one of those labels must carry five identity fields:
| Field | Example | Purpose |
|---|---|---|
domainKey |
salesforce:rosetta-core |
Which domain authored it |
stableKey |
pattern:cl-042 |
Semantic identity within the domain |
qualifiedKey |
salesforce:rosetta-core::pattern:cl-042 |
Global MERGE key (unique per label, schema-enforced) |
displayId |
CL-042 |
Human-readable handle |
overrideMode |
base |
Resolution mode in the stack |
The root domain is salesforce:rosetta-core — all canonical seed content is rooted
there with overrideMode: base, and only admin-role actors may write to it. Child
domains (<vendor>:<product>, <client>:<engagement>) inherit the canon and may
override it with the other four modes: supplement (add alongside), refine
(selectively override an ancestor), replace, and suppress (hide an ancestor from
this domain's view). Eight relationship types are correspondingly domain-aware,
carrying domainKey / relationKey / overrideMode edge properties for stack
resolution.
An assessor should note the maturity honestly: the schema enforces qualifiedKey
uniqueness, but Neo4j Community Edition cannot enforce property-existence or edge-
property constraints, so the rest of the contract is application-layer enforced (on
the write path, and by the load-time invariant gates) — and the seed data at snapshot
exercises only base mode, with the override modes reserved for engagement-fork
scenarios as the multi-engagement model matures. The inheritance mechanism is
architecture that is ahead of its current usage.
2.5 The provenance and authorship lanes¶
The v1.10/v1.11 additions are small in schema surface and large in consequence — they are what Chapter 5's stages 5–7 run on. Every twin node carries two orthogonal axes, deliberately not collapsed into one enum:
provenance ∈ {confirmed, simulated}— the forensic boundary. Absent means confirmed (there was no migration; legacy content is grandfathered by read-time coalescing). Simulated content carries asimulationRunIdpurge handle so an entire rehearsal run can be reverted in one statement.reviewStatus ∈ {draft, agent-authored, human-ratified, rejected}— the authorship ladder, a one-way state machine with two terminal states. Agent output isagent-authoredby default;human-ratifiedstamps a humanreviewedBy; re-proposal after rejection is a new node, never a transition out of a terminal state. Batch ratification over asimulationRunIdskips already-terminal nodes, so re-runs are idempotent.
Two enforcement details are worth an assessor's attention because they show the system's style. First, the load-time gate for these enums (INV-D37) is deliberately WARNING-tier, never fail-closed — a conscious departure from an earlier invariant whose hard failure red-failed committed goldens and forced a production reload; the hard enforcement lives at apply time instead (a 422 on a bad value). Second, the metamodel document itself carries an operational trap note: production's restricted apoc allowlist forbids the dynamic-key apoc map functions, and the CI job that checks Cypher syntax runs unrestricted apoc — so only the corpus-replay lane (restricted, like production) catches that class of violation. A metamodel that documents its own CI blind spot is unusual, and characteristic.
2.6 What to read next¶
The metamodel document itself (rosetta-platform/docs/rosetta-semantic-metamodel-
v1.11.0.md) rewards a full read: §0 is the versioned decision history, §3–4 the node
and edge catalogs with the enforcement Cypher inline, §13 the invariants the schema
cannot express, and Appendix B its own known-drift register. The schema files it
projects (db/schema/01..46) are the ground truth. Chapter 6 picks up the governance
node families in motion; Chapter 5 already showed the twin families in use.