# Engram Standard
## The Open Standard for Portable, Governed AI Memory
> Created: 2026-04-20
> Status: RFC Draft v0.1 — Not yet published
> Author: Ashish (8mem)
> License: Creative Commons CC-BY 4.0

---

## Part 1 — What Is Engram (Plain Language)

### The Problem Every AI User Has Today

You use ChatGPT. It learns you prefer short emails.
You open Claude. Starts from zero.
You use a voice assistant. Starts from zero.
You buy a new AI tool. Starts from zero.

Every AI you use keeps your memory locked inside itself.
You own nothing. You take nothing with you. You explain yourself forever.

### What Engram Is

Engram is a **standard format** for your AI memory.

Like a passport — every country agrees on the format, so it works everywhere.
Engram is a format every AI system agrees to read, so your memory works everywhere.

It stores:
- **Who you are** — name, timezone, role, background
- **What you prefer** — how you communicate, work, think, make decisions
- **What you've corrected** — "no, I changed my mind about X"
- **How you've evolved** — "in January I believed X, by April I believed Y"

### The One-Sentence Definition

> Engram is your AI memory card — visible to you, controlled by you, readable by any AI, owned by no one but you.

### What Engram Is NOT

- Not a product you install
- Not an AI assistant
- Not a database owned by a company
- Not another walled garden

It is a **format specification** — like JSON, like HTML, like OAuth.
Anyone can implement it. No one owns it. Everyone benefits.

---

## Part 2 — Why This Standard Must Exist

### The Current State (Broken)

| AI System | Your Memory | Portable? | You Control It? |
|-----------|------------|-----------|----------------|
| ChatGPT Memory | Locked in OpenAI | No | Partially |
| Claude Memory | Locked in Anthropic | No | No |
| Google Assistant | Locked in Google | No | No |
| Any AI agent | Locked in that tool | No | No |

Every company has incentive to **lock your memory inside their product**.
Your memory is their moat. You are the product.

### What Engram Changes

| With Engram | Result |
|-------------|--------|
| Memory stored in standard format | Any AI can read it |
| User holds their own export | Portability is real |
| Signed and verified | Any runtime can trust it |
| User can correct and govern it | You control what AI knows about you |
| Open spec, no owner | No single company can lock it down |

### Why Now

The AI memory space is about to be defined — permanently.
The first open standard published with runtime adoption becomes the default.
Every month of delay is a month a funded competitor can get there first.

---

## Part 3 — The Full Technical Specification (v0.1)

### 3.1 Schema Overview

Engram defines four core objects:

```
IDENTITY     — who the user is (stable facts)
BELIEFS      — what the user prefers, thinks, does (dynamic facts)
EVOLUTION    — how beliefs changed over time (history)
CORRECTIONS  — explicit user overrides (audit trail)
```

### 3.2 Top-Level Envelope

```json
{
  "engram_version": "0.1",
  "schema": "https://engramspec.org/schema/v0.1",
  "issued_at": "2026-04-20T10:00:00Z",
  "expires_at": "2026-04-20T22:00:00Z",
  "kid": "key-2026-04",
  "issuer": {
    "name": "8mem",
    "url": "https://8mem.com",
    "did": "did:web:8mem.com"
  },
  "subject": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "display_name": "Ashish"
  },
  "scope": "full",
  "signature": "base64url-ed25519-signature",
  "identity": { ... },
  "beliefs": [ ... ],
  "evolution": [ ... ],
  "corrections": [ ... ]
}
```

**Field definitions:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| engram_version | string | Yes | Spec version used |
| issued_at | ISO8601 | Yes | When this export was generated |
| expires_at | ISO8601 | Yes | When this export expires. MUST be set. Recommended maximum: 24 hours from issued_at |
| kid | string | Yes | Key ID identifying which key in `/.well-known/engram-keys` was used to sign this export. Required for correct key rotation. Runtimes MUST use this to select the verification key, not try all keys. |
| issuer.name | string | Yes | Human-readable name of the issuing system |
| issuer.url | string | Yes | URL of the issuing system |
| issuer.did | string | No | DID of the issuer for verifiable credential workflows |
| subject.id | string | Yes | Stable opaque identifier for the user. MUST be a UUIDv4 or a URI. Unique within the issuer's namespace. Not an email or PII. |
| subject.display_name | string | No | Human-readable name for display only |
| scope | string | Yes | "full" / "professional" / "personal" / "financial" / "minimal" / "custom" |
| signature | string | Yes | Ed25519 signature of canonical payload (see §3.8) |

**Important:** `expires_at: null` is not valid in v0.1. Every export MUST have an expiry. A runtime receiving an export with no expiry SHOULD treat it as expired.

---

### 3.3 IDENTITY Object

Stable facts about the user. Changes rarely.

```json
"identity": {
  "display_name": "Ashish",
  "timezone": "Asia/Singapore",
  "locale": "en-SG",
  "role": "Founder",
  "domains": ["AI", "product", "startups"],
  "bio": "Building 8mem — AI memory layer",
  "created_at": "2026-01-01T00:00:00Z",
  "last_updated": "2026-04-20T10:00:00Z"
}
```

**Field definitions:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| display_name | string | Yes | How the user wants to be addressed |
| timezone | string | Yes | IANA timezone (e.g. Asia/Singapore) |
| locale | string | No | BCP-47 language tag |
| role | string | No | User's primary role |
| domains | array[string] | No | Areas of expertise or interest |
| bio | string | No | Short free-text self-description |

---

### 3.4 BELIEFS Array

Dynamic facts — preferences, habits, working style, opinions. These change over time.

```json
"beliefs": [
  {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "category": "communication",
    "key": "email_style",
    "value": "short, direct, no fluff",
    "value_type": "string",
    "confidence": 0.95,
    "source": "user_stated",
    "status": "active",
    "created_at": "2026-01-15T09:00:00Z",
    "last_confirmed": "2026-04-10T14:00:00Z",
    "stale_after_days": 90,
    "tags": ["email", "writing", "communication"]
  },
  {
    "id": "550e8400-e29b-41d4-a716-446655440002",
    "category": "work_style",
    "key": "meeting_preference",
    "value": "async first, weekly sync acceptable",
    "value_type": "string",
    "confidence": 0.80,
    "source": "inferred",
    "status": "active",
    "created_at": "2026-02-10T11:00:00Z",
    "last_confirmed": "2026-03-20T09:00:00Z",
    "stale_after_days": 60,
    "tags": ["meetings", "async", "work"]
  }
]
```

**Field definitions:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| id | string | Yes | Unique belief ID (UUIDv4). Stable across exports — never reuse an ID even after deletion |
| category | string | Yes | High-level group (see categories below) |
| key | string | Yes | What this belief is about |
| value | string | Yes | The belief content in natural language |
| value_type | string | No | Hint for runtimes: "string" (default) / "boolean" / "number" / "enum". Allows structured parsing without breaking the natural language value |
| confidence | float 0–1 | Yes | How certain the system is. Below 0.5 = uncertain, surface to user before acting |
| source | string | Yes | "user_stated" / "inferred" / "corrected" |
| status | string | Yes | "active" / "archived" / "deleted". Deleted beliefs MUST still appear in exports with status "deleted" so runtimes can purge their caches (tombstone pattern) |
| created_at | ISO8601 | Yes | When first captured |
| last_confirmed | ISO8601 | No | When user last validated this |
| stale_after_days | int | No | Days after `last_confirmed` before a belief is considered stale. The server exports the original `confidence` value unchanged — the signature covers the stored value. Staleness adjustment is a **client-side** computation: runtimes MAY reduce displayed confidence by 0.1 per day overdue (minimum 0.3) when deciding how to use the belief. Stale beliefs MUST NOT be excluded from exports — runtimes decide how to handle them. |
| tags | array[string] | No | Searchable labels |

**Standard belief categories:**

| Category | Covers |
|----------|--------|
| communication | Email style, response speed, channel preferences |
| work_style | Async vs sync, meeting preferences, focus patterns |
| decision_making | How user makes decisions, risk tolerance |
| relationships | Notes about specific people the user interacts with |
| projects | Current work, priorities, active initiatives |
| values | What the user cares about, what they avoid |
| learning | How user learns, what they're studying |
| health | Relevant health context (if user chooses to store) |
| financial | Financial preferences and context (scoped export) |
| custom | Any domain not covered above |

---

### 3.5 EVOLUTION Array

The history of how beliefs changed. The "before and after" that makes 8mem unique.

```json
"evolution": [
  {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "belief_id": "550e8400-e29b-41d4-a716-446655440001",
    "old_value": "formal, detailed, structured",
    "new_value": "short, direct, no fluff",
    "changed_at": "2026-02-01T10:00:00Z",
    "trigger": "user_correction",
    "context": "user said during onboarding: 'I write short emails, stop making them formal'",
    "note": "user explicitly updated their style preference"
  },
  {
    "id": "660e8400-e29b-41d4-a716-446655440002",
    "belief_id": "550e8400-e29b-41d4-a716-446655440002",
    "old_value": "no meetings at all",
    "new_value": "async first, weekly sync acceptable",
    "changed_at": "2026-03-15T14:00:00Z",
    "trigger": "contradiction_resolution",
    "context": "user mentioned starting weekly team syncs with new hire",
    "note": "user said they started weekly team syncs — resolved with user"
  }
]
```

**Field definitions:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| id | string | Yes | Unique evolution record ID (UUIDv4) |
| belief_id | string | Yes | Which belief this tracks |
| old_value | string | Yes | What it was before |
| new_value | string | Yes | What it became |
| changed_at | ISO8601 | Yes | When the change happened |
| trigger | string | Yes | "user_correction" / "contradiction_resolution" / "natural_update" / "expiry" |
| context | string | No | The conversational or situational context that caused this change. Enables auditing and debugging. Example: "user mentioned starting a new job during onboarding" |
| note | string | No | Human-readable explanation of the change |

---

### 3.6 CORRECTIONS Array

Explicit user overrides — the audit trail of trust.

```json
"corrections": [
  {
    "id": "770e8400-e29b-41d4-a716-446655440001",
    "belief_id": "550e8400-e29b-41d4-a716-446655440001",
    "corrected_by": "user",
    "corrected_at": "2026-02-01T10:00:00Z",
    "old_value": "formal, detailed, structured",
    "new_value": "short, direct, no fluff",
    "method": "explicit",
    "note": "user typed: 'no, I write short emails'"
  }
]
```

**Field definitions:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| id | string | Yes | Unique correction ID |
| belief_id | string | Yes | Which belief was corrected |
| corrected_by | string | Yes | "user" / "system" / "governance_rule" |
| corrected_at | ISO8601 | Yes | When correction happened |
| old_value | string | Yes | What was wrong |
| new_value | string | Yes | What is correct |
| method | string | Yes | "explicit" (user typed it) / "implicit" (inferred) / "approved" (governance) |
| note | string | No | Raw user input that triggered correction |

---

### 3.7 Scoped Exports

Not all memory should be shared everywhere. Engram supports scoped exports.

`scope` and `scope_definition` are top-level envelope fields alongside `identity`, `beliefs`, etc. When `scope` is not `full`, `scope_definition` SHOULD be present to describe the constraints applied.

```json
{
  "engram_version": "0.1",
  "issued_at": "2026-04-20T10:00:00Z",
  "expires_at": "2026-04-20T22:00:00Z",
  "kid": "key-2026-04",
  "issuer": { "name": "8mem", "url": "https://8mem.com" },
  "subject": { "id": "550e8400-e29b-41d4-a716-446655440000", "display_name": "Ashish" },
  "scope": "professional",
  "scope_definition": {
    "included_categories": ["communication", "work_style", "projects", "decision_making"],
    "excluded_categories": ["health", "financial", "relationships"],
    "purpose": "shared with accountant AI assistant",
    "issued_to": "https://accountant-ai.example.com",
    "valid_until": "2026-07-20T00:00:00Z"
  },
  "signature": "base64url-ed25519-signature",
  "identity": { ... },
  "beliefs": [ ... ],
  "evolution": [ ... ],
  "corrections": [ ... ]
}
```

**scope_definition fields:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| included_categories | array[string] | Yes (for custom) | Categories included in this export |
| excluded_categories | array[string] | No | Categories explicitly excluded |
| purpose | string | No | Human-readable reason for this scoped export |
| issued_to | string (URI) | No | URI identifying the runtime this scope was issued for. MUST be a URI (https://, did:, or urn:) — not a freeform string. Enables consent tracking when delegation model is defined in v0.2. |
| valid_until | ISO8601 | No | When this scoped export expires |

**Standard scopes:**

| Scope | Included Categories |
|-------|-------------------|
| full | Everything |
| professional | communication, work_style, projects, decision_making, values |
| personal | relationships, health, learning, custom |
| financial | financial only |
| minimal | identity + communication only |
| custom | User-defined category list |

---

### 3.8 Signature and Verification

Every Engram export is signed using **Ed25519** (asymmetric — private key signs, public key verifies). This allows any runtime to verify an export without sharing secrets.

**Signing process (issuer side):**
```
1. Remove the "signature" field from the envelope
2. Serialize the remaining payload as canonical JSON
   (keys sorted alphabetically, no whitespace, UTF-8)
3. Sign with the issuer's Ed25519 private key
4. Base64url-encode the 64-byte signature
5. Store in the "signature" field
```

**Verification process (runtime side):**
```
1. Extract and remove the "signature" field
2. Re-serialize the remaining payload as canonical JSON
   (same rules as above — must be byte-for-byte identical)
3. Read the "kid" field from the envelope. If absent, reject — invalid export.
4. Fetch the key list from: GET {issuer.url}/.well-known/engram-keys
5. Select the key where keys[n].kid matches the envelope "kid" value.
   If no matching key is found, reject — key may have been rotated or revoked.
6. Verify the Ed25519 signature against the matched public key.
7. Check expires_at is in the future.
8. If all checks pass: trust the context.
   If any check fails: reject and log. Do not use the context.
```

**Key distribution — `/.well-known/engram-keys`:**

Every Engram-compatible issuer MUST expose:
```
GET /.well-known/engram-keys
```
Response:
```json
{
  "keys": [
    {
      "kid": "key-2026-04",
      "alg": "Ed25519",
      "use": "sig",
      "public_key": "base64url-encoded-32-byte-public-key",
      "created_at": "2026-04-01T00:00:00Z",
      "expires_at": "2027-04-01T00:00:00Z"
    }
  ]
}
```

Multiple keys may be listed to support key rotation. Runtimes MUST use the `kid` field from the export envelope to select the correct key. If `kid` is absent (invalid export), reject it.

**Note:** v0.1 uses Ed25519 directly. Future versions will add JWT/JWK and W3C Verifiable Credentials support for interoperability with broader identity ecosystems.

---

### 3.9 API Contract

Any system that serves Engram context MUST implement the following endpoints.

**Authentication:** All endpoints require `Authorization: Bearer {token}`. In v0.1, token issuance is handled by the Engram store's own auth system. A standardised delegation and consent flow (how users grant runtimes scoped access) is planned for v0.2. See §12 — Known Limitations.

---

#### Error Response Format

All endpoints return errors in this shape:

```json
{
  "error": {
    "code": "belief_not_found",
    "message": "No belief with id b_999 exists for this user",
    "status": 404
  }
}
```

**Standard error codes:**

| Code | HTTP Status | Meaning |
|------|-------------|---------|
| `unauthorized` | 401 | Token missing or invalid |
| `token_expired` | 401 | Token has expired |
| `forbidden` | 403 | Token valid but insufficient scope |
| `user_not_found` | 404 | No Engram record for this subject |
| `belief_not_found` | 404 | Belief ID does not exist |
| `invalid_scope` | 400 | Unknown or malformed scope value |
| `invalid_request` | 400 | Malformed request body |
| `rate_limited` | 429 | Too many requests |
| `unsupported_version` | 400 | engram_version in request is not supported by this server |
| `server_error` | 500 | Internal error |

---

#### `GET /v1/context`
Returns the user's full Engram export.

**Request:**
```
GET /v1/context
Authorization: Bearer {token}
Accept: application/json
```

**Response: 200 OK**
```json
{
  "engram_version": "0.1",
  "schema": "https://engramspec.org/schema/v0.1",
  "issued_at": "2026-04-20T10:00:00Z",
  "expires_at": "2026-04-20T22:00:00Z",
  "kid": "key-2026-04",
  "issuer": { ... },
  "subject": { ... },
  "scope": "full",
  "signature": "base64url-ed25519-signature",
  "identity": { ... },
  "beliefs": [ ... ],
  "evolution": [ ... ],
  "corrections": [ ... ]
}
```

---

#### `GET /v1/context?scope={scope}`
Returns a scoped export. Signature covers only the included fields.

```
GET /v1/context?scope=professional
Authorization: Bearer {token}
```

---

#### `GET /v1/context?categories={cat1}&categories={cat2}`
Returns beliefs from specific categories only. Use repeated query parameters.

```
GET /v1/context?categories=communication&categories=work_style
Authorization: Bearer {token}
```

---

#### `POST /v1/context/correct`
Submits a correction from a runtime. The Engram store MUST record this as a CORRECTION with `corrected_by: "runtime"`. The store MUST NOT automatically apply it as `corrected_by: "user"` — user confirmation is required before a runtime-submitted correction becomes authoritative.

**Request:**
```json
{
  "belief_id": "550e8400-e29b-41d4-a716-446655440001",
  "new_value": "I now prefer longer emails for investor updates",
  "context": "user said this during a session about investor comms",
  "runtime_id": "openclaw-v2026.4",
  "timestamp": "2026-04-20T11:00:00Z"
}
```

| Field | Required | Description |
|-------|----------|-------------|
| belief_id | Yes | UUID of the belief to correct |
| new_value | Yes | The proposed corrected value |
| context | No | Conversational context that triggered this correction |
| runtime_id | Yes | Identifier of the runtime submitting the correction. Displayed to the user during confirmation so they know which integration proposed the change. |
| timestamp | Yes | ISO8601 timestamp of when the correction was observed |

**Response: 201 Created**
```json
{
  "correction_id": "770e8400-e29b-41d4-a716-446655440002",
  "belief_id": "550e8400-e29b-41d4-a716-446655440001",
  "status": "pending_user_confirmation",
  "message": "Correction recorded. Awaiting user confirmation before becoming authoritative."
}
```

---

#### `GET /v1/context/diff?since={ISO8601}`
Returns only beliefs that changed since the given timestamp. Used by runtimes that cache context to avoid re-fetching everything.

**Request:**
```
GET /v1/context/diff?since=2026-04-19T10:00:00Z
Authorization: Bearer {token}
```

**Response: 200 OK**
```json
{
  "engram_version": "0.1",
  "since": "2026-04-19T10:00:00Z",
  "generated_at": "2026-04-20T10:00:00Z",
  "changes": {
    "beliefs": {
      "added": [ ... ],
      "updated": [ ... ],
      "deleted": [
        { "id": "550e8400-e29b-41d4-a716-446655440003", "status": "deleted", "deleted_at": "2026-04-20T08:00:00Z" }
      ]
    },
    "corrections": {
      "added": [ ... ]
    },
    "evolution": {
      "added": [ ... ]
    }
  }
}
```

Deleted beliefs appear as tombstones in the `deleted` array so runtimes can purge their caches.

**Security note:** The diff response is not independently signed. Runtimes that require tamper-proof deltas MUST call `GET /v1/context` for a full signed export rather than trusting the diff channel alone. The diff endpoint is an optimisation for trusted channels, not a replacement for signature verification.

---

#### `GET /.well-known/engram`
Discovery endpoint. Returns metadata about this Engram store.

**Response: 200 OK**
```json
{
  "engram_version": "0.1",
  "issuer": {
    "name": "8mem",
    "url": "https://8mem.com"
  },
  "endpoints": {
    "context": "/v1/context",
    "correct": "/v1/context/correct",
    "diff": "/v1/context/diff",
    "keys": "/.well-known/engram-keys"
  },
  "scopes_supported": ["full", "professional", "personal", "financial", "minimal"],
  "auth_note": "Token issuance handled by issuer. Standardised delegation flow in v0.2."
}
```

---

### 3.10 Versioning Rules

| Version | Meaning |
|---------|---------|
| 0.x | Draft / RFC phase — breaking changes allowed with discussion |
| 1.0 | Stable — no breaking changes without major version bump |
| 1.x | Backwards-compatible additions only. Old exports remain valid. |
| 2.0 | Breaking change — migration guide required, old exporters must migrate |

**Runtime compatibility:**

Runtimes MUST check `engram_version` and handle unknown versions as follows:
- If `engram_version` is a higher 0.x than supported: warn and attempt to parse, ignoring unknown fields
- If `engram_version` is 1.x and runtime supports 1.0: accept (backwards compatible)
- If `engram_version` major version is higher than supported: reject with `{"error": {"code": "unsupported_version", "message": "Supported versions: 0.x", "status": 400}}`

Do not hard-reject on minor version differences — this creates unnecessary upgrade cliffs.

**Export validity across versions:**
Exports generated under 0.1 remain parseable under 1.0. The 1.0 spec will define any required field additions as optional with defaults. A migration guide will be published alongside 1.0.

---

## Part 4 — Reference Implementation

**8mem** is the reference implementation of the Engram standard.

| Feature | Status |
|---------|--------|
| Memory capture (BELIEFS) | Live ✓ |
| Correction loop (CORRECTIONS) | Live ✓ |
| Contradiction detection | Live ✓ |
| /passport (IDENTITY view) | Live ✓ |
| Evolution tracking | In testing ⚙️ |
| Point-in-time reconstruction | In testing ⚙️ |
| Signed exports | Planned 📋 |
| GET /v1/context API | Planned 📋 |
| Scoped exports | Planned 📋 |

GitHub: https://github.com/engramspec/spec
Docs: https://engramspec.org

---

## Part 5 — How Runtimes Implement Engram

### Minimal Implementation (Day 1)

A runtime only needs to do two things to be "Engram compatible":

1. Call `GET /v1/context` at session start
2. Inject the response into the LLM system prompt

```python
# Minimal Engram integration — any runtime
# user_token: a Bearer token issued by the user's Engram store.
# In v0.1, obtain this from your Engram store's auth system.
# Standardised token issuance flow is defined in v0.2.
import requests
from datetime import datetime, timezone

def get_user_context(engram_base_url: str, user_token: str) -> str:
    response = requests.get(
        f"{engram_base_url}/v1/context",
        headers={"Authorization": f"Bearer {user_token}"}
    )
    response.raise_for_status()
    engram = response.json()

    # Check expiry
    expires_at = datetime.fromisoformat(engram["expires_at"].replace("Z", "+00:00"))
    if expires_at < datetime.now(timezone.utc):
        raise ValueError("Engram export has expired — fetch a fresh one")

    identity = engram["identity"]
    # Only inject active beliefs with sufficient confidence
    beliefs = [b for b in engram["beliefs"]
               if b.get("status") == "active" and b.get("confidence", 0) >= 0.5]

    context = f"User: {identity['display_name']}\n"
    context += f"Timezone: {identity['timezone']}\n\n"
    context += "What I know about this user:\n"
    for belief in beliefs:
        context += f"- {belief['key']}: {belief['value']}\n"
    return context

# Before LLM call:
user_context = get_user_context("https://your-8mem-instance", user_token)
system_prompt = f"{base_system_prompt}\n\n{user_context}"
```

### Full Implementation

Full implementation adds:
- Correction submission (`POST /v1/context/correct`)
- Incremental sync (`GET /v1/context/diff?since=...`)
- Signature verification
- Scoped context requests

---

## Part 6 — Adoption

### What "Engram Compatible" Means

A runtime is Engram compatible when it:
1. Calls `GET /v1/context` at session start
2. Injects the response into the LLM system prompt
3. Links to this spec in its documentation

That's the minimum. Full compatibility adds correction submission and incremental sync.

---

### Adoption Tiers

| Tier | What it means |
|------|--------------|
| Reader | Calls `GET /v1/context` — memory works at session start |
| Writer | Also calls `POST /v1/context/correct` — corrections flow back |
| Full | Implements all endpoints including `diff` for incremental sync |

Reader tier is sufficient to be listed as Engram compatible.

---

### Listing Your Implementation

Open a GitHub Issue with label `implementation` and include:
- Your project name and URL
- Which tier you implement
- A link to your integration code or docs

---

## Part 7 — FAQ for Runtime Developers

**Q: Do I have to use 8mem to implement Engram?**
No. Engram is a format spec. You can build your own Engram-compatible memory store.

**Q: Is this a paid standard?**
No. CC-BY 4.0 — free to use, implement, fork. Attribution required.

**Q: What if I only want to read context, not send corrections back?**
Read-only implementation is valid. `GET /v1/context` is the only required endpoint.

**Q: Does Engram require cloud storage?**
No. 8mem is local-first. The standard works with any storage backend.

**Q: What about privacy?**
The user controls what is exported and to whom. Scoped exports mean users share only what they choose.

**Q: How is this different from OpenAI's memory?**
OpenAI memory is locked to ChatGPT. Engram is portable — works with any AI. OpenAI will never implement Engram because portability helps their competitors.

---

## Part 8 — Why This Standard Will Win

### The Trust Argument
Every big AI company has incentive to lock memory inside their product.
They will never publish a portable memory standard — it helps competitors.
Engram can only come from a neutral party. 8mem is that party.

### The Developer Argument
Developers hate rebuilding user context for every AI tool they integrate.
A standard format means: integrate once, memory works everywhere.
Engram saves every AI developer days of work. Developers adopt what saves them time.

### The User Argument
Users are beginning to understand that AI memory = AI lock-in.
The first product that says "your memory belongs to you, take it anywhere" wins user trust.
That product is 8mem. That format is Engram.

### The Standards Argument
De facto standards win when:
1. The problem is real and widely felt ✓
2. The first mover publishes openly (not as a product) ✓
3. The reference implementation works ✓
4. Early adopters exist before competitors notice ✓

All four conditions are achievable in 2 weeks.

---

## Part 9 — What Happens If We Don't Move Fast

| Timeline | Risk |
|----------|------|
| Week 1–2 | Safe. No competitor has this. |
| Week 3–4 | A funded startup could notice and move |
| Month 2 | If VC-backed, they can publish faster with more marketing |
| Month 3+ | If a big framework (LangChain, AutoGPT) publishes their own — very hard to displace |

**The window is now. The cost of publishing is one day of work.**

---

## Appendix A — Full Example Export

```json
{
  "engram_version": "0.1",
  "schema": "https://engramspec.org/schema/v0.1",
  "issued_at": "2026-04-20T10:00:00Z",
  "expires_at": "2026-04-20T22:00:00Z",
  "kid": "key-2026-04",
  "issuer": {
    "name": "8mem",
    "url": "https://8mem.com",
    "did": "did:web:8mem.com"
  },
  "subject": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "display_name": "Ashish"
  },
  "scope": "full",
  "signature": "base64url-ed25519-signature-here",
  "identity": {
    "display_name": "Ashish",
    "timezone": "Asia/Singapore",
    "locale": "en-SG",
    "role": "Founder",
    "domains": ["AI", "product", "startups"],
    "created_at": "2026-01-01T00:00:00Z",
    "last_updated": "2026-04-20T10:00:00Z"
  },
  "beliefs": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "category": "communication",
      "key": "email_style",
      "value": "short, direct, no fluff",
      "value_type": "string",
      "confidence": 0.95,
      "source": "user_stated",
      "status": "active",
      "created_at": "2026-01-15T09:00:00Z",
      "last_confirmed": "2026-04-10T14:00:00Z",
      "stale_after_days": 90,
      "tags": ["email", "writing"]
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "category": "work_style",
      "key": "meeting_preference",
      "value": "async first, weekly sync acceptable",
      "value_type": "string",
      "confidence": 0.80,
      "source": "inferred",
      "status": "active",
      "created_at": "2026-02-10T11:00:00Z",
      "last_confirmed": "2026-03-20T09:00:00Z",
      "stale_after_days": 60,
      "tags": ["meetings", "async"]
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440003",
      "category": "projects",
      "key": "current_focus",
      "value": "Building 8mem — shipping GET /v1/context API",
      "value_type": "string",
      "confidence": 1.0,
      "source": "user_stated",
      "status": "active",
      "created_at": "2026-04-18T09:00:00Z",
      "last_confirmed": "2026-04-20T10:00:00Z",
      "stale_after_days": 14,
      "tags": ["8mem", "startup", "api"]
    }
  ],
  "evolution": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "belief_id": "550e8400-e29b-41d4-a716-446655440001",
      "old_value": "formal, detailed, structured",
      "new_value": "short, direct, no fluff",
      "changed_at": "2026-02-01T10:00:00Z",
      "trigger": "user_correction",
      "context": "user said during onboarding: 'I write short emails, stop making them formal'",
      "note": "user explicitly updated writing preference"
    }
  ],
  "corrections": [
    {
      "id": "770e8400-e29b-41d4-a716-446655440001",
      "belief_id": "550e8400-e29b-41d4-a716-446655440001",
      "corrected_by": "user",
      "corrected_at": "2026-02-01T10:00:00Z",
      "old_value": "formal, detailed, structured",
      "new_value": "short, direct, no fluff",
      "method": "explicit",
      "note": "user typed: 'I write short emails, stop making them formal'"
    }
  ]
}
```

---

## Appendix B — Changelog

| Version | Date | Changes |
|---------|------|---------|
| 0.1 | 2026-04-20 | Initial draft. Core schema: IDENTITY, BELIEFS, EVOLUTION, CORRECTIONS. Basic API contract. Scoped exports. |

---

---

## Part 10 — Why Anyone Cares (The Human Argument)

### Why Would Anyone Care?

Only one real reason: **they've felt the pain personally.**

Every developer who has built an AI product has hit this moment:
> "How do I remember who this user is across sessions?"

They solve it badly — a JSON file, a database column, a system prompt hack. It works but it's brittle, unportable, and they built it from scratch.

When Engram exists, they don't build it. They call one endpoint. That's it.

**Users care for a different reason:**
> "I've been using ChatGPT for a year. It knows how I think. I tried Claude for one task and had to explain myself from scratch. That's broken."

Every person who has felt that frustration is a potential Engram believer. That number is growing every month as AI usage goes mainstream.

---

### Why Would Someone Champion It?

Honest answer: most people won't, at first.

The people who will champion it early:

| Who | Why They Care |
|-----|--------------|
| Indie AI developers | Saves them a week of work. They tweet about tools that save them time. |
| Privacy-conscious users | "My memory belongs to me" is a strong identity statement for them. |
| AI runtime builders | Being "Engram compatible" = marketing claim. Costs them one integration. |
| Developers building on multiple AI tools | They feel the pain of no standard more than anyone. |

The mass of people don't champion standards. They just use them silently. HTTP, OAuth, JSON — nobody marches for these. But every developer uses them without thinking. That's the goal.

---

### Why Can't Someone Copy the Whole Thing?

**They can. And you should want them to.**

This is the part that sounds counterintuitive:

> An open standard that nobody copies is a failed standard.
> An open standard that everyone copies is a winning standard.

HTTP was "copied" by every browser, every server, every framework. That's why it won.

**What copying looks like for Engram:**

- Someone publishes a competing spec → they're fragmenting the market, not winning it. Developers hate fragmentation. They'll pick the one with more adoption.
- Someone implements Engram in their product → they just validated the standard and made 8mem more valuable.
- A big company (OpenAI, Anthropic) implements Engram → 8mem won. The standard became infrastructure.

**What actually cannot be copied:**

| Thing | Why |
|-------|-----|
| First-mover credibility | "They defined the standard" is permanent history |
| Reference implementation trust | 8mem is the one that works, others are catching up |
| Community momentum | Stars, forks, early adopters — these compound |
| The narrative | "Portable AI memory — open standard by 8mem" — once it exists in the world, it belongs to 8mem |

---

### The Honest Brutal Truth

Right now — today — nobody cares about Engram. It doesn't exist publicly.

The question is not "why will people care."
The question is: **what is the smallest thing that makes the first 10 developers care?**

That answer is simple:
> A working code example that calls `GET /v1/context` and makes their AI product remember users in 20 lines of code.

One developer tweets that. Another sees it. Third tries it. That's how standards start — not with a manifesto, but with one person saying "this saved me time."

**The real risk is not copying. The real risk is nobody noticing.**

That's why the HN post and the working reference implementation matter more than the spec document itself.

---

## Part 11 — Domain and Web Presence

### Official Domains

| Domain | Purpose |
|--------|---------|
| `engramspec.org` | Primary — standards live on .org |
| `engramspec.com` | Redirect to .org — block squatters |

Both registered 2026-04-20. ~$20/year total.

### Why engramspec.org

- "spec" is the exact right word for a developer standard
- No hyphen — clean, easy to type, easy to say
- Reads like a proper standards body
- Pattern matches: openid.net, schema.org, openapi.org

### Web Presence Minimum (Day 1)

- GitHub: `github.com/engramspec/spec` — the RFC lives here
- `engramspec.org` → GitHub Pages pointing to the spec
- No fancy website needed at launch — developers trust GitHub more than landing pages

---

## Part 12 — Known Limitations and v0.2 Roadmap

This section documents gaps that are known, deliberate, and planned for v0.2. Publishing these honestly is how a standard earns trust.

---

### 12.1 — No Delegation or Consent Flow (The Biggest Gap)

v0.1 assumes the runtime already holds a valid user token issued by the Engram store. It does not define:
- How a user grants a specific runtime access to their Engram store
- How a user scopes that access (e.g. "this runtime can only read professional scope")
- How a user revokes that access

This is the core problem OAuth solves. Engram v0.1 sidesteps it intentionally — shipping the schema and API first, then layering the trust model on top.

**v0.2 will define:**
- An authorization flow: user → Engram store → issues scoped access token for runtime
- Token scoping aligned with the export scopes (§3.7)
- Token revocation endpoint
- Consent record stored in the Engram export

Until v0.2, runtimes integrate using tokens issued directly by the Engram store's own auth system.

---

### 12.2 — No Multi-Store Discovery or Conflict Resolution

v0.1 assumes one Engram store per user. It does not define:
- How a runtime discovers which Engram store a user has
- What happens when a user has two Engram-compatible stores
- How to merge or reconcile conflicting beliefs across stores

**v0.2 will define:** a user-level discovery mechanism (similar to WebFinger) and merge semantics for multi-store scenarios.

---

### 12.3 — No Machine-Readable JSON Schema

The field definitions in this document are normative but expressed in markdown tables. A JSON Schema file for validation is planned.

**Will be published at:** `https://engramspec.org/schema/v0.1.json`

---

### 12.4 — No Bulk Correction

`POST /v1/context/correct` accepts one correction at a time. Bulk correction (e.g. migrating from another memory system) is not defined in v0.1.

**v0.2 will define:** `POST /v1/context/correct/batch`

---

### 12.5 — Pull-Only Model

All v0.1 endpoints are pull-based. Runtimes that want real-time updates must poll `GET /v1/context/diff`. A push/webhook model is not defined.

**v0.2 will define:** `POST /v1/context/subscribe` for webhook registration.

---

### 12.6 — Reference Implementation Signature Stub

The v0.1 8mem reference implementation may return `signature.value: "unsigned-v1"` while the API shape stabilizes.

`unsigned-v1` is not an Ed25519 signature. Runtimes MUST NOT treat it as cryptographically verified. If an export contains `signature.value: "unsigned-v1"`, treat it as an unsigned reference export and rely only on the authenticated transport or local trust boundary that delivered it.

Full Ed25519 signing, key discovery, and verification behavior are planned for v0.2 before any enterprise-grade trust claim.

---

*This document is the Engram Standard RFC v0.1*
*Publish to GitHub at: github.com/engramspec/spec*
*Website: https://engramspec.org*
*Reference implementation: 8mem (https://8mem.com)*
*License: CC-BY 4.0*
