Guides

Practical, implementer-facing how-tos. The specification is the contract; these guides are the on-ramp. Everything below is grounded in the R1 schemas and the conformant examples/minimal-bundle.omir in the repository.

1 · Your first .omir Bundle

An OMIR document is a Bundle: a small envelope (resourceType, omirVersion, entry[]) wrapping a flat list of typed resources. Resources don't nest — they link by typed reference of the form ResourceType/id. Here is a complete, conformant Bundle: one Entity and one MemoryRecord that references it.

{
  "resourceType": "Bundle",
  "omirVersion": "R1",
  "entry": [
    {
      "resourceType": "Entity",
      "id": "rust",
      "name": "Rust programming",
      "labels": ["technology", "skill"],
      "salience": 0.8
    },
    {
      "resourceType": "MemoryRecord",
      "id": "m1",
      "content": "The team standardized on Rust for the reference validator.",
      "createdAt": "2026-06-01T09:00:00Z",
      "kind": "learning",
      "experienceType": "decision",
      "importance": 0.8,
      "entityRefs": [{ "ref": "Entity/rust" }]
    }
  ]
}

That's it. The MemoryRecord.entityRefs[] entry Entity/rust resolves to the Entity with id: "rust" in the same Bundle — that resolution is a conformance rule (see step 3).

2 · Validate before you share

Don't guess at conformance — check it. The reference validator (omir-validate, Apache-2.0) decides whether a file is a valid R1 Bundle and to what level. It checks structural validity against the schemas, reference integrity (every ResourceType/id resolves within the Bundle), and the R1 version marker.

# from the repository root
cd validator
cargo run -- ../examples/minimal-bundle.omir

#   structural ............. pass   (5 entries: 2 Entity, 1 Episode, 1 MemoryRecord, 1 Relationship)
#   reference integrity .... pass   (7 of 7 references resolved)
#   version presence ....... pass   (Bundle=R1, 5/5 entries meta.omirVersion=R1)
#
# RESULT: PASS  —  Core conformant ✓  (badge-eligible)

A clean --level core run (exit code 0) is exactly what gates the "Powered by OMIR" badge. Use --format json for CI and badge automation. See Conformance for the full rule set.

3 · Reference integrity

OMIR is closed-world for references in R1: a Bundle is self-contained, and every typed reference must resolve to an entry of the right type in the same Bundle. A dangling reference is non-conformant.

ReferenceMust target
MemoryRecord.entityRefs[], Episode.entityRefs[]an Entity
Relationship.from / .toan Entity
Relationship.sourceEpisodean Episode
MemoryRecord.parentIda MemoryRecord

The validator's negative corpus in examples/invalid/ shows what rejection looks like — a dangling ref, a score out of range, a bad enum, an undeclared field.

4 · Keep proprietary data in extension[]

The R1 core is an 80/20 set: the fields ~80% of memory systems share. Every resource schema sets additionalProperties: false, so a new top-level field is non-conformant by construction. That's deliberate — your bespoke data rides in the typed extension[] array, under a URL you control:

"extension": [
  {
    "url": "https://your-company.example/omir/ext/scoring-signals",
    "valueJson": { "recency": 0.91, "graphStrength": 0.62, "arousal": 0.40 }
  }
]

A consumer that doesn't recognize the url must ignore it and still process the record. That single rule is what lets two engines exchange Bundles and lose nothing: the shared 80% is interoperable; the proprietary 20% travels safely alongside it.

5 · Migrating from an existing memory store

Most memory engines (Mem0, Letta, or a homegrown store) already track the same concepts under different names. Migration is mostly a field-mapping exercise; the cognitive richness OMIR carries — calibrated confidence, decay/anchoring, Hebbian edge strength, tiering — maps onto core fields rather than getting flattened away.

In your storeOMIR
memory / document textMemoryRecord.content
created vs. happened timecreatedAt vs. eventTime
score / weightimportance (a [0,1] UnitInterval)
tags / named thingsEntity + entityRefs[]
graph edgesRelationship (from/to/strength)
raw source event / transcriptEpisode
vendor scores, embeddings, signalsextension[] (never the core)

Start as a producer: emit Core-conformant Bundles from your export path, validate them, then list yourself on Implementations.

Where to go next