# 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*:

```mermaid
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: `SemanticEntity` defines canonical concepts
  ("Individual," "UnifiedAccount"); `ContextPattern` defines validated implementation
  plays ("Hybrid Commerce Identity Resolution").
- **Layer 3** is what actually runs on the target platform: the `Individual__dlm`
  data-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 a `simulationRunId` purge 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 is
  `agent-authored` by default; `human-ratified` stamps a human `reviewedBy`;
  re-proposal after rejection is a new node, never a transition out of a terminal
  state. Batch ratification over a `simulationRunId` skips 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.
